00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include "TStreamerInfo.h"
00035 #include "TFile.h"
00036 #include "TROOT.h"
00037 #include "TClonesArray.h"
00038 #include "TStreamerElement.h"
00039 #include "TClass.h"
00040 #include "TClassEdit.h"
00041 #include "TDataMember.h"
00042 #include "TMethodCall.h"
00043 #include "TDataType.h"
00044 #include "TRealData.h"
00045 #include "TBaseClass.h"
00046 #include "TBuffer.h"
00047 #include "TArrayC.h"
00048 #include "TArrayI.h"
00049 #include "TArrayF.h"
00050 #include "TArrayD.h"
00051 #include "TArrayS.h"
00052 #include "TArrayL.h"
00053 #include "TError.h"
00054 #include "TRef.h"
00055 #include "TProcessID.h"
00056
00057 #include "TStreamer.h"
00058 #include "TContainerConverters.h"
00059 #include "TCollectionProxyFactory.h"
00060 #include "TVirtualCollectionProxy.h"
00061 #include "TInterpreter.h"
00062
00063 #include "TMemberInspector.h"
00064
00065 #include "TMakeProject.h"
00066
00067 #include "TSchemaRuleSet.h"
00068 #include "TSchemaRule.h"
00069
00070 #include "TVirtualMutex.h"
00071
00072 #include "TStreamerInfoActions.h"
00073
00074 TStreamerElement *TStreamerInfo::fgElement = 0;
00075 Int_t TStreamerInfo::fgCount = 0;
00076
00077 const Int_t kRegrouped = TStreamerInfo::kOffsetL;
00078
00079 const Int_t kMaxLen = 1024;
00080
00081 ClassImp(TStreamerInfo)
00082
00083 static void R__TObjArray_InsertAt(TObjArray *arr, TObject *obj, Int_t at)
00084 {
00085
00086 Int_t last = arr->GetLast();
00087 arr->AddAtAndExpand(arr->At(last),last+1);
00088 for(Int_t ind = last-1; ind >= at; --ind) {
00089 arr->AddAt( arr->At(ind), ind+1);
00090 };
00091 arr->AddAt( obj, at);
00092 }
00093
00094 #if 0
00095 static void R__TObjArray_InsertAfter(TObjArray *arr, TObject *newobj, TObject *oldobj)
00096 {
00097
00098 Int_t last = arr->GetLast();
00099 Int_t at = 0;
00100 while (at<last && arr->At(at) != oldobj) {
00101 ++at;
00102 }
00103 if (at!=0) {
00104 ++at;
00105 }
00106 R__TObjArray_InsertAt(arr, newobj, at);
00107 }
00108 #endif
00109
00110 static void R__TObjArray_InsertBefore(TObjArray *arr, TObject *newobj, TObject *oldobj)
00111 {
00112
00113 Int_t last = arr->GetLast();
00114 Int_t at = 0;
00115 while (at<last && arr->At(at) != oldobj) {
00116 ++at;
00117 }
00118 R__TObjArray_InsertAt(arr, newobj, at);
00119 }
00120
00121
00122 TStreamerInfo::TStreamerInfo()
00123 {
00124
00125
00126 fNumber = fgCount;
00127 fClass = 0;
00128 fElements = 0;
00129 fComp = 0;
00130 fType = 0;
00131 fNewType = 0;
00132 fOffset = 0;
00133 fLength = 0;
00134 fElem = 0;
00135 fMethod = 0;
00136 fCheckSum = 0;
00137 fNdata = 0;
00138 fSize = 0;
00139 fClassVersion = 0;
00140 fOnFileClassVersion = 0;
00141 fOldVersion = Class()->GetClassVersion();
00142 fNVirtualInfoLoc = 0;
00143 fVirtualInfoLoc = 0;
00144 fLiveCount = 0;
00145
00146 fReadObjectWise = 0;
00147 fReadMemberWise = 0;
00148 }
00149
00150
00151 TStreamerInfo::TStreamerInfo(TClass *cl)
00152 : TVirtualStreamerInfo(cl)
00153 {
00154
00155
00156 fgCount++;
00157 fNumber = fgCount;
00158 fClass = cl;
00159 fElements = new TObjArray();
00160 fComp = 0;
00161 fType = 0;
00162 fNewType = 0;
00163 fOffset = 0;
00164 fLength = 0;
00165 fElem = 0;
00166 fMethod = 0;
00167 fCheckSum = 0;
00168 fNdata = 0;
00169 fSize = 0;
00170 fClassVersion = fClass->GetClassVersion();
00171 fOnFileClassVersion = 0;
00172 fOldVersion = Class()->GetClassVersion();
00173 fNVirtualInfoLoc = 0;
00174 fVirtualInfoLoc = 0;
00175 fLiveCount = 0;
00176
00177 fReadObjectWise = 0;
00178 fReadMemberWise = 0;
00179 }
00180
00181
00182 TStreamerInfo::~TStreamerInfo()
00183 {
00184
00185
00186 delete [] fType; fType =0;
00187 delete [] fNewType; fNewType=0;
00188 delete [] fOffset; fOffset =0;
00189 delete [] fLength; fLength =0;
00190 delete [] fElem; fElem =0;
00191 delete [] fMethod; fMethod =0;
00192 delete [] fComp; fComp =0;
00193 delete [] fVirtualInfoLoc; fVirtualInfoLoc =0;
00194
00195 delete fReadObjectWise;
00196 delete fReadMemberWise;
00197
00198 if (!fElements) return;
00199 fElements->Delete();
00200 delete fElements; fElements=0;
00201 }
00202
00203
00204 void TStreamerInfo::Build()
00205 {
00206
00207
00208
00209
00210 R__LOCKGUARD(gCINTMutex);
00211
00212
00213 fIsBuilt = kTRUE;
00214
00215 if (fClass->GetCollectionProxy()) {
00216
00217 TStreamerElement* element = new TStreamerSTL("This", "Used to call the proper TStreamerInfo case", 0, fClass->GetName(), fClass->GetName(), 0);
00218 fElements->Add(element);
00219 Compile();
00220 return;
00221 }
00222
00223 TStreamerElement::Class()->IgnoreTObjectStreamer();
00224
00225 fClass->BuildRealData();
00226
00227 fCheckSum = fClass->GetCheckSum();
00228
00229 Bool_t needAllocClass = kFALSE;
00230 Bool_t wasCompiled = fOffset != 0;
00231 const ROOT::TSchemaMatch* rules = 0;
00232 if (fClass->GetSchemaRules()) {
00233 rules = fClass->GetSchemaRules()->FindRules(fClass->GetName(), fClassVersion);
00234 }
00235
00236
00237
00238
00239
00240 TBaseClass* base = 0;
00241 TIter nextb(fClass->GetListOfBases());
00242 while ((base = (TBaseClass*)nextb())) {
00243 TStreamerElement* element = 0;
00244 Int_t offset = base->GetDelta();
00245 if (offset == kMissing) {
00246 continue;
00247 }
00248 const char* bname = base->GetName();
00249 const char* btitle = base->GetTitle();
00250
00251 if (!strcmp(bname, "string")) {
00252 element = new TStreamerSTLstring(bname, btitle, offset, bname, kFALSE);
00253 } else if (base->IsSTLContainer()) {
00254 element = new TStreamerSTL(bname, btitle, offset, bname, 0, kFALSE);
00255 } else {
00256 element = new TStreamerBase(bname, btitle, offset);
00257 TClass* clm = element->GetClassPointer();
00258 if (!clm) {
00259 Error("Build", "%s, unknown type: %s %s\n", GetName(), bname, btitle);
00260 delete element;
00261 element = 0;
00262 } else {
00263 clm->GetStreamerInfo();
00264 if ((clm == TObject::Class()) && fClass->CanIgnoreTObjectStreamer()) {
00265
00266
00267
00268
00269 SetBit(kIgnoreTObjectStreamer);
00270
00271
00272
00273 element->SetType(-1);
00274 }
00275 if (!clm->IsLoaded()) {
00276 Warning("Build:", "%s: base class %s has no streamer or dictionary it will not be saved", GetName(), clm->GetName());
00277 }
00278 }
00279 }
00280 if (element) {
00281 fElements->Add(element);
00282 }
00283 }
00284
00285
00286
00287
00288
00289 Int_t dsize;
00290 TDataMember* dm = 0;
00291 TIter nextd(fClass->GetListOfDataMembers());
00292 while ((dm = (TDataMember*) nextd())) {
00293 if (fClass->GetClassVersion() == 0) {
00294 continue;
00295 }
00296 if (!dm->IsPersistent()) {
00297 continue;
00298 }
00299 TMemberStreamer* streamer = 0;
00300 Int_t offset = GetDataMemberOffset(dm, streamer);
00301 if (offset == kMissing) {
00302 continue;
00303 }
00304 TStreamerElement* element = 0;
00305 dsize = 0;
00306 const char* dmName = dm->GetName();
00307 const char* dmTitle = dm->GetTitle();
00308 const char* dmType = dm->GetTypeName();
00309 const char* dmFull = dm->GetFullTypeName();
00310 Bool_t dmIsPtr = dm->IsaPointer();
00311 TDataMember* dmCounter = 0;
00312 if (dmIsPtr) {
00313
00314
00315
00316
00317
00318
00319
00320 const char* lbracket = ::strchr(dmTitle, '[');
00321 const char* rbracket = ::strchr(dmTitle, ']');
00322 if (lbracket && rbracket) {
00323 const char* counterName = dm->GetArrayIndex();
00324 TRealData* rdCounter = (TRealData*) fClass->GetListOfRealData()->FindObject(counterName);
00325 if (!rdCounter || rdCounter->TestBit(TRealData::kTransient)) {
00326 Error("Build", "%s, discarding: %s %s, illegal %s\n", GetName(), dmFull, dmName, dmTitle);
00327 continue;
00328 }
00329 dmCounter = rdCounter->GetDataMember();
00330 TDataType* dtCounter = dmCounter->GetDataType();
00331 Bool_t isInteger = dtCounter && ((dtCounter->GetType() == 3) || (dtCounter->GetType() == 13));
00332 if (!dtCounter || !isInteger) {
00333 Error("Build", "%s, discarding: %s %s, illegal [%s] (must be Int_t)\n", GetName(), dmFull, dmName, counterName);
00334 continue;
00335 }
00336 TStreamerBasicType* bt = TStreamerInfo::GetElementCounter(counterName, dmCounter->GetClass());
00337 if (!bt) {
00338 if (dmCounter->GetClass()->Property() & kIsAbstract) {
00339 continue;
00340 }
00341 Error("Build", "%s, discarding: %s %s, illegal [%s] must be placed before \n", GetName(), dmFull, dmName, counterName);
00342 continue;
00343 }
00344 }
00345 }
00346 TDataType* dt = dm->GetDataType();
00347 if (dt) {
00348
00349 Int_t dtype = dt->GetType();
00350 dsize = dt->Size();
00351 if (!dmCounter && (strstr(dmFull, "char*") || strstr(dmFull, "Char_t*"))) {
00352 dtype = kCharStar;
00353 dsize = sizeof(char*);
00354 }
00355 if (dmIsPtr && (dtype != kCharStar)) {
00356 if (dmCounter) {
00357
00358 element = new TStreamerBasicPointer(dmName, dmTitle, offset, dtype, dm->GetArrayIndex(), dmCounter->GetClass()->GetName(), dmCounter->GetClass()->GetClassVersion(), dmFull);
00359 } else {
00360 if ((fName == "TString") || (fName == "TClass")) {
00361 continue;
00362 }
00363 Error("Build", "%s, discarding: %s %s, no [dimension]\n", GetName(), dmFull, dmName);
00364 continue;
00365 }
00366 } else {
00367
00368 if ((fClass == TObject::Class()) && !strcmp(dmName, "fBits")) {
00369
00370 dtype = kBits;
00371 }
00372 element = new TStreamerBasicType(dmName, dmTitle, offset, dtype, dmFull);
00373 }
00374 } else {
00375
00376 static const char* full_string_name = "basic_string<char,char_traits<char>,allocator<char> >";
00377 if (!strcmp(dmType, "string") || !strcmp(dmType, full_string_name)) {
00378 element = new TStreamerSTLstring(dmName, dmTitle, offset, dmFull, dmIsPtr);
00379 } else if (dm->IsSTLContainer()) {
00380 element = new TStreamerSTL(dmName, dmTitle, offset, dmFull, dm->GetTrueTypeName(), dmIsPtr);
00381 } else {
00382 TClass* clm = TClass::GetClass(dmType);
00383 if (!clm) {
00384 Error("Build", "%s, unknown type: %s %s\n", GetName(), dmFull, dmName);
00385 continue;
00386 }
00387 if (dmIsPtr) {
00388
00389 if (dmCounter) {
00390 element = new TStreamerLoop(dmName, dmTitle, offset, dm->GetArrayIndex(), dmCounter->GetClass()->GetName(), dmCounter->GetClass()->GetClassVersion(), dmFull);
00391 } else {
00392 if (clm->InheritsFrom(TObject::Class())) {
00393 element = new TStreamerObjectPointer(dmName, dmTitle, offset, dmFull);
00394 } else {
00395 element = new TStreamerObjectAnyPointer(dmName, dmTitle, offset, dmFull);
00396 if (!streamer && !clm->GetStreamer() && !clm->IsLoaded()) {
00397 Error("Build:", "%s: %s has no streamer or dictionary, data member %s will not be saved", GetName(), dmFull, dmName);
00398 }
00399 }
00400 }
00401 } else if (clm->InheritsFrom(TObject::Class())) {
00402 element = new TStreamerObject(dmName, dmTitle, offset, dmFull);
00403 } else if ((clm == TString::Class()) && !dmIsPtr) {
00404 element = new TStreamerString(dmName, dmTitle, offset);
00405 } else {
00406 element = new TStreamerObjectAny(dmName, dmTitle, offset, dmFull);
00407 if (!streamer && !clm->GetStreamer() && !clm->IsLoaded()) {
00408 Warning("Build:", "%s: %s has no streamer or dictionary, data member \"%s\" will not be saved", GetName(), dmFull, dmName);
00409 }
00410 }
00411 }
00412 }
00413 if (!element) {
00414
00415 continue;
00416 }
00417 Int_t ndim = dm->GetArrayDim();
00418 if (!dsize) {
00419 dsize = dm->GetUnitSize();
00420 }
00421 for (Int_t i = 0; i < ndim; ++i) {
00422 element->SetMaxIndex(i, dm->GetMaxIndex(i));
00423 }
00424 element->SetArrayDim(ndim);
00425 Int_t narr = element->GetArrayLength();
00426 if (!narr) {
00427 narr = 1;
00428 }
00429 element->SetSize(dsize*narr);
00430 element->SetStreamer(streamer);
00431 if (!streamer) {
00432 Int_t k = element->GetType();
00433 if (k == kStreamer) {
00434
00435 element->SetType(-1);
00436 }
00437 }
00438
00439 if ( !wasCompiled && (rules && rules->HasRuleWithSource( element->GetName(), kTRUE )) ) {
00440 needAllocClass = kTRUE;
00441
00442
00443
00444
00445
00446 TStreamerElement *cached = element;
00447
00448 if (element->GetNewType()>0
00449 && rules && !rules->HasRuleWithTarget( element->GetName(), kTRUE ) )
00450 {
00451 TStreamerElement *copy = (TStreamerElement*)element->Clone();
00452 fElements->Add(copy);
00453 copy->SetBit(TStreamerElement::kRepeat);
00454 cached = copy;
00455
00456
00457 }
00458 cached->SetBit(TStreamerElement::kCache);
00459 cached->SetNewType( cached->GetType() );
00460 }
00461
00462 fElements->Add(element);
00463 }
00464
00465
00466 InsertArtificialElements(rules);
00467
00468 if (needAllocClass) {
00469 TStreamerInfo *infoalloc = (TStreamerInfo *)Clone(TString::Format("%s@@%d",GetName(),GetClassVersion()));
00470 infoalloc->BuildCheck();
00471 infoalloc->BuildOld();
00472 TClass *allocClass = infoalloc->GetClass();
00473
00474 {
00475 TIter next(fElements);
00476 TStreamerElement* element;
00477 while ((element = (TStreamerElement*) next())) {
00478 if (element->TestBit(TStreamerElement::kRepeat) && element->IsaPointer()) {
00479 TStreamerElement *other = (TStreamerElement*) infoalloc->GetElements()->FindObject(element->GetName());
00480 if (other) {
00481 other->SetBit(TStreamerElement::kDoNotDelete);
00482 }
00483 }
00484 }
00485 infoalloc->GetElements()->Compress();
00486 }
00487 {
00488 TIter next(fElements);
00489 TStreamerElement* element;
00490 while ((element = (TStreamerElement*) next())) {
00491 if (element->TestBit(TStreamerElement::kCache)) {
00492 element->SetOffset(infoalloc->GetOffset(element->GetName()));
00493 }
00494 }
00495 }
00496
00497 TStreamerElement *el = new TStreamerArtificial("@@alloc","", 0, TStreamerInfo::kCacheNew, allocClass->GetName());
00498 R__TObjArray_InsertAt( fElements, el, 0 );
00499
00500 el = new TStreamerArtificial("@@dealloc","", 0, TStreamerInfo::kCacheDelete, allocClass->GetName());
00501 fElements->Add( el );
00502 }
00503
00504
00505
00506
00507 Compile();
00508 }
00509
00510
00511 void TStreamerInfo::BuildCheck()
00512 {
00513
00514
00515
00516 R__LOCKGUARD(gCINTMutex);
00517
00518 TObjArray* array = 0;
00519 fClass = TClass::GetClass(GetName());
00520 if (!fClass) {
00521 fClass = new TClass(GetName(), fClassVersion, 0, 0, -1, -1);
00522 fClass->SetBit(TClass::kIsEmulation);
00523 array = fClass->GetStreamerInfos();
00524 } else {
00525 if (TClassEdit::IsSTLCont(fClass->GetName())) {
00526 SetBit(kCanDelete);
00527 return;
00528 }
00529 array = fClass->GetStreamerInfos();
00530 TStreamerInfo* info = 0;
00531
00532 if (fClass->TestBit(TClass::kIsEmulation) && array->GetEntries()==0) {
00533
00534
00535
00536
00537
00538 ::Warning("TClass::TClass", "no dictionary for class %s is available", GetName());
00539 }
00540
00541
00542
00543
00544
00545
00546
00547 Bool_t searchOnChecksum = kFALSE;
00548 if (fClass->IsLoaded() && fClass->GetClassVersion() >= 2) {
00549
00550
00551 if (fOnFileClassVersion >= 2) {
00552
00553
00554
00555 searchOnChecksum = kFALSE;
00556
00557 } else {
00558
00559
00560
00561 searchOnChecksum = kTRUE;
00562 }
00563 } else if (fClass->IsLoaded() && !fClass->IsForeign()) {
00564
00565
00566
00567
00568 searchOnChecksum = kFALSE;
00569
00570 } else if (fClass->IsLoaded() ) {
00571
00572
00573
00574 searchOnChecksum = kTRUE;
00575
00576 }
00577 else {
00578
00579
00580 if (fOnFileClassVersion >= 2) {
00581
00582
00583
00584 searchOnChecksum = kFALSE;
00585
00586 } else {
00587
00588
00589
00590 searchOnChecksum = kTRUE;
00591
00592 TStreamerInfo* v1 = (TStreamerInfo*) array->At(1);
00593 if (v1) {
00594 if (fCheckSum != v1->GetCheckSum()) {
00595 fClassVersion = array->GetLast() + 1;
00596 }
00597 }
00598 }
00599 }
00600
00601 if (!searchOnChecksum) {
00602 if (fClassVersion < array->GetEntriesFast()) {
00603 info = (TStreamerInfo*) array->At(fClassVersion);
00604 }
00605 } else {
00606 Int_t ninfos = array->GetEntriesFast() - 1;
00607 for (Int_t i = -1; i < ninfos; ++i) {
00608 info = (TStreamerInfo*) array->UncheckedAt(i);
00609 if (!info) {
00610 continue;
00611 }
00612 if (fCheckSum == info->GetCheckSum() && (info->GetOnFileClassVersion()==1 || info->GetOnFileClassVersion()==0)) {
00613
00614
00615 fClassVersion = i;
00616 break;
00617 }
00618 info = 0;
00619 }
00620 if (info==0) {
00621
00622 ninfos = array->GetEntriesFast() - 1;
00623 Int_t slot = 1;
00624 while ((slot < ninfos) && (array->UncheckedAt(slot) != 0)) {
00625 ++slot;
00626 }
00627 fClassVersion = slot;
00628 }
00629 }
00630
00631
00632
00633
00634
00635
00636 if (info) {
00637
00638 Bool_t match = kTRUE;
00639 Bool_t done = kFALSE;
00640 Bool_t oldIsNonVersioned = kFALSE;
00641 if (fClassVersion!=0 && !fClass->TestBit(TClass::kWarned) && (fClassVersion == info->GetClassVersion()) && (fCheckSum != info->GetCheckSum())) {
00642
00643
00644 match = kFALSE;
00645 oldIsNonVersioned = info->fOnFileClassVersion==1 && info->fClassVersion != 1;
00646
00647 if (fClass->IsLoaded() && (fClassVersion == fClass->GetClassVersion()) && fClass->GetListOfDataMembers() && (fClass->GetClassInfo())) {
00648
00649
00650
00651
00652
00653
00654
00655
00656 if ( (fCheckSum == fClass->GetCheckSum() || fCheckSum == fClass->GetCheckSum(1) || fCheckSum == fClass->GetCheckSum(2))
00657 &&(info->GetCheckSum() == fClass->GetCheckSum() || info->GetCheckSum() == fClass->GetCheckSum(1) || info->GetCheckSum() == fClass->GetCheckSum(2))
00658 )
00659 {
00660 match = kTRUE;
00661 }
00662 if (fOldVersion <= 2) {
00663
00664
00665 match = kTRUE;
00666 }
00667 if (!match && CompareContent(0,info,kFALSE,kFALSE)) {
00668 match = kTRUE;
00669 }
00670 } else {
00671
00672
00673 match = kFALSE;
00674 oldIsNonVersioned = info->fOnFileClassVersion==1 && info->fClassVersion != 1;
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684 if (fCheckSum == info->GetCheckSum(0) || fCheckSum == info->GetCheckSum(1) || fCheckSum == info->GetCheckSum(2)
00685 || GetCheckSum(0) == info->GetCheckSum() || GetCheckSum(1) == info->GetCheckSum() || GetCheckSum(2) == info->GetCheckSum()
00686 || GetCheckSum(0) == info->GetCheckSum(0))
00687 {
00688 match = kTRUE;
00689 }
00690 if (fOldVersion <= 2) {
00691
00692
00693 match = kTRUE;
00694 }
00695 if (!match && CompareContent(0,info,kFALSE,kFALSE)) {
00696 match = kTRUE;
00697 }
00698 }
00699 }
00700 if (info->IsBuilt()) {
00701 SetBit(kCanDelete);
00702 fNumber = info->GetNumber();
00703 Int_t nel = fElements->GetEntriesFast();
00704 TObjArray* elems = info->GetElements();
00705 TStreamerElement* e1 = 0;
00706 TStreamerElement* e2 = 0;
00707 for (Int_t i = 0; i < nel; ++i) {
00708 e1 = (TStreamerElement*) fElements->UncheckedAt(i);
00709 e2 = (TStreamerElement*) elems->At(i);
00710 if (!e1 || !e2) {
00711 continue;
00712 }
00713 if (strlen(e1->GetTitle()) != strlen(e2->GetTitle())) {
00714 e2->SetTitle(e1->GetTitle());
00715 }
00716 }
00717
00718 if (TestBit(kCannotOptimize)) {
00719 info->SetBit(TVirtualStreamerInfo::kCannotOptimize);
00720 if (info->IsOptimized())
00721 {
00722
00723 info->Compile();
00724 }
00725 }
00726 done = kTRUE;
00727 } else {
00728 array->RemoveAt(fClassVersion);
00729 delete info;
00730 info = 0;
00731 }
00732 TString origin;
00733 if (!match && !fClass->TestBit(TClass::kWarned)) {
00734 if (oldIsNonVersioned) {
00735 if (gDirectory && gDirectory->GetFile()) {
00736 Warning("BuildCheck", "\n\
00737 The class %s transitioned from not having a specified class version\n\
00738 to having a specified class version (the current class version is %d).\n\
00739 However too many different non-versioned layouts of the class have been\n\
00740 loaded so far. This prevent the proper reading of objects written with\n\
00741 the class layout version %d, in particular from the file:\n\
00742 %s.\n\
00743 To work around this issue, load fewer 'old' files in the same ROOT session.",
00744 GetName(),fClass->GetClassVersion(),fClassVersion,gDirectory->GetFile()->GetName());
00745 } else {
00746 Warning("BuildCheck", "\n\
00747 The class %s transitioned from not having a specified class version\n\
00748 to having a specified class version (the current class version is %d).\n\
00749 However too many different non-versioned layouts of the class have been\n\
00750 loaded so far. This prevent the proper reading of objects written with\n\
00751 the class layout version %d.\n\
00752 To work around this issue, load fewer 'old' files in the same ROOT session.",
00753 GetName(),fClass->GetClassVersion(),fClassVersion);
00754 }
00755 } else {
00756 if (gDirectory && gDirectory->GetFile()) {
00757 if (done) {
00758 Warning("BuildCheck", "\n\
00759 The StreamerInfo for version %d of class %s read from the file %s\n\
00760 has a different checksum than the previously loaded StreamerInfo.\n\
00761 Reading objects of type %s from the file %s \n\
00762 (and potentially other files) might not work correctly.\n\
00763 Most likely the version number of the class was not properly\n\
00764 updated [See ClassDef(%s,%d)].",
00765 fClassVersion, GetName(), gDirectory->GetFile()->GetName(), GetName(), gDirectory->GetFile()->GetName(), GetName(), fClassVersion);
00766 } else {
00767 Warning("BuildCheck", "\n\
00768 The StreamerInfo from %s does not match existing one (%s:%d)\n\
00769 The existing one has not been used yet and will be discarded.\n\
00770 Reading the file %s will work properly, however writing object of\n\
00771 type %s will not work properly. Most likely the version number\n\
00772 of the class was not properly updated [See ClassDef(%s,%d)].",
00773 gDirectory->GetFile()->GetName(), GetName(), fClassVersion,gDirectory->GetFile()->GetName(),GetName(), GetName(), fClassVersion);
00774 }
00775 } else {
00776 if (done) {
00777 Warning("BuildCheck", "\n\
00778 The StreamerInfo for version %d of class %s\n\
00779 has a different checksum than the previously loaded StreamerInfo.\n\
00780 Reading objects of type %s\n\
00781 (and potentially other files) might not work correctly.\n\
00782 Most likely the version number of the class was not properly\n\
00783 updated [See ClassDef(%s,%d)].",
00784 fClassVersion, GetName(), GetName(), GetName(), fClassVersion);
00785 } else {
00786 Warning("BuildCheck", "\n\
00787 The StreamerInfo from %s does not match existing one (%s:%d)\n\
00788 The existing one has not been used yet and will be discarded.\n\
00789 Reading should work properly, however writing object of\n\
00790 type %s will not work properly. Most likely the version number\n\
00791 of the class was not properly updated [See ClassDef(%s,%d)].",
00792 gDirectory->GetFile()->GetName(), GetName(), fClassVersion, GetName(), GetName(), fClassVersion);
00793 }
00794 }
00795 }
00796 CompareContent(0,info,kTRUE,kTRUE);
00797 fClass->SetBit(TClass::kWarned);
00798 }
00799 if (done) {
00800 return;
00801 }
00802 }
00803
00804
00805 if (fClass->IsLoaded()
00806 && fClass->GetListOfDataMembers()
00807 && (fClassVersion != 0)
00808 && (fClassVersion == fClass->GetClassVersion())
00809 && (fCheckSum != fClass->GetCheckSum())
00810 && (fClass->GetClassInfo())) {
00811
00812
00813
00814
00815
00816
00817
00818 if (fCheckSum != fClass->GetCheckSum(1) && fCheckSum != fClass->GetCheckSum(2)) {
00819
00820 Bool_t warn = !fClass->TestBit(TClass::kWarned);
00821 if (warn && (fOldVersion <= 2)) {
00822
00823
00824 TIter nextBC(fClass->GetListOfBases());
00825 TBaseClass* bc = 0;
00826 while ((bc = (TBaseClass*) nextBC())) {
00827 if (TClassEdit::IsSTLCont(bc->GetName())) {
00828 warn = kFALSE;
00829 }
00830 }
00831 }
00832 if (warn) {
00833 if (gDirectory && gDirectory->GetFile()) {
00834 Warning("BuildCheck", "\n\
00835 The StreamerInfo of class %s read from file %s\n\
00836 has the same version (=%d) as the active class but a different checksum.\n\
00837 You should update the version to ClassDef(%s,%d).\n\
00838 Do not try to write objects with the current class definition,\n\
00839 the files will not be readable.\n", GetName(), gDirectory->GetFile()->GetName(), fClassVersion, GetName(), fClassVersion + 1);
00840 } else {
00841 Warning("BuildCheck", "\n\
00842 The StreamerInfo of class %s \n\
00843 has the same version (=%d) as the active class but a different checksum.\n\
00844 You should update the version to ClassDef(%s,%d).\n\
00845 Do not try to write objects with the current class definition,\n\
00846 the files will not be readable.\n", GetName(), fClassVersion, GetName(), fClassVersion + 1);
00847 }
00848 fClass->SetBit(TClass::kWarned);
00849 }
00850 } else {
00851 if (fClass->IsForeign()) {
00852 R__ASSERT(0);
00853 }
00854 }
00855 }
00856 if (!fClass->IsLoaded() && this->fOnFileClassVersion>1)
00857 {
00858 ROOT::ResetClassVersion(fClass,(const char*)-1, this->fClassVersion);
00859 }
00860 }
00861
00862
00863
00864 if (TestBit(kIgnoreTObjectStreamer)) {
00865 fClass->IgnoreTObjectStreamer();
00866 }
00867 if ((fClassVersion < -1) || (fClassVersion > 65000)) {
00868 printf("ERROR reading TStreamerInfo: %s fClassVersion=%d\n", GetName(), fClassVersion);
00869 SetBit(kCanDelete);
00870 fNumber = -1;
00871 return;
00872 }
00873
00874 array->AddAtAndExpand(this, fClassVersion);
00875 ++fgCount;
00876 fNumber = fgCount;
00877
00878
00879 fIsBuilt = kTRUE;
00880
00881
00882 TObjArray* infos = (TObjArray*) gROOT->GetListOfStreamerInfo();
00883 infos->AddAtAndExpand(this, fNumber);
00884 }
00885
00886
00887 void TStreamerInfo::BuildEmulated(TFile *file)
00888 {
00889
00890
00891 R__LOCKGUARD(gCINTMutex);
00892
00893 TString duName;
00894 R__ASSERT(file);
00895 Int_t fv = file->GetVersion()%100000;
00896 R__ASSERT(fv < 30000);
00897 fClassVersion = -1;
00898 fCheckSum = 2001;
00899 TObjArray *elements = GetElements();
00900 if (!elements) return;
00901 Int_t ndata = elements->GetEntries();
00902 if (ndata == 0) return;
00903 TStreamerElement *element;
00904 Int_t i;
00905 for (i=0;i < ndata;i++) {
00906 element = (TStreamerElement*)elements->UncheckedAt(i);
00907 if (!element) break;
00908 int ty = element->GetType();
00909 if (ty < kChar || ty >kULong+kOffsetL) continue;
00910 if (ty == kLong) element->SetType(kInt);
00911 if (ty == kULong) element->SetType(kUInt);
00912 if (ty == kLong + kOffsetL) element->SetType(kInt + kOffsetL);
00913 if (ty == kULong + kOffsetL) element->SetType(kUInt + kOffsetL);
00914 if (ty <= kULong) continue;
00915 duName = element->GetName();
00916 duName.Append("QWERTY");
00917 TStreamerBasicType *bt = new TStreamerBasicType(duName, "", 0, kInt,"Int_t");
00918 {for (int j=ndata-1;j>=i;j--) {elements->AddAtAndExpand(elements->At(j),j+1);}}
00919 elements->AddAt(bt,i);
00920 ndata++;
00921 i++;
00922 }
00923 BuildOld();
00924 }
00925
00926
00927 Bool_t TStreamerInfo::BuildFor( const TClass *in_memory_cl )
00928 {
00929
00930
00931
00932
00933 R__LOCKGUARD(gCINTMutex);
00934
00935 if( !in_memory_cl || !in_memory_cl->GetSchemaRules() )
00936 return kFALSE;
00937
00938 const TObjArray* rules;
00939
00940 rules = in_memory_cl->GetSchemaRules()->FindRules( GetName(), fOnFileClassVersion, fCheckSum );
00941
00942 if( !rules && !TClassEdit::IsSTLCont( in_memory_cl->GetName() ) ) {
00943 Warning( "BuildFor", "The build of %s streamer info for %s has been requested, but no matching conversion rules were specified", GetName(), in_memory_cl->GetName() );
00944 return kFALSE;
00945 }
00946
00947 fClass = const_cast<TClass*>(in_memory_cl);
00948
00949 return kTRUE;
00950 }
00951
00952
00953
00954 namespace {
00955 Bool_t ClassWasMovedToNamespace(TClass *oldClass, TClass *newClass)
00956 {
00957
00958
00959
00960 if (oldClass == 0 || newClass == 0) return kFALSE;
00961
00962 UInt_t newlen = strlen(newClass->GetName());
00963 UInt_t oldlen = strlen(oldClass->GetName());
00964
00965 const char *oldname = oldClass->GetName();
00966 for (UInt_t i = oldlen, done = false, nest = 0; (i>0) && !done ; --i) {
00967 switch (oldClass->GetName()[i-1]) {
00968 case '>' : ++nest; break;
00969 case '<' : --nest; break;
00970 case ':' : if (nest == 0) oldname= &(oldClass->GetName()[i]); done = kTRUE; break;
00971 }
00972 }
00973 oldlen = strlen(oldname);
00974 if (!(strlen(newClass->GetName()) > strlen(oldClass->GetName()))) {
00975 return kFALSE;
00976 }
00977
00978 const char* newEnd = & (newClass->GetName()[newlen-oldlen]);
00979
00980 if (0 != strcmp(newEnd, oldname)) {
00981 return kFALSE;
00982 }
00983
00984 Int_t oldv = oldClass->GetStreamerInfo()->GetClassVersion();
00985
00986 if (newClass->GetStreamerInfos() && oldv < newClass->GetStreamerInfos()->GetSize() && newClass->GetStreamerInfos()->At(oldv) && strcmp(newClass->GetStreamerInfos()->At(oldv)->GetName(), oldClass->GetName()) != 0) {
00987
00988
00989
00990 return kFALSE;
00991 }
00992 return kTRUE;
00993 }
00994
00995 Int_t ImportStreamerInfo(TClass *oldClass, TClass *newClass) {
00996
00997
00998
00999
01000
01001 TIter next(oldClass->GetStreamerInfos());
01002 TStreamerInfo *info;
01003 while ((info = (TStreamerInfo*)next())) {
01004 info = (TStreamerInfo*)info->Clone();
01005 info->SetClass(newClass);
01006 Int_t oldv = info->GetClassVersion();
01007 if (oldv > newClass->GetStreamerInfos()->GetSize() || newClass->GetStreamerInfos()->At(oldv) == 0) {
01008
01009 newClass->GetStreamerInfos()->AddAtAndExpand(info,oldv);
01010 } else {
01011
01012
01013
01014 if (strcmp(newClass->GetStreamerInfos()->At(oldv)->GetName(),
01015 oldClass->GetName()) != 0) {
01016
01017
01018 return oldv;
01019 }
01020 }
01021 }
01022 return 0;
01023 }
01024
01025 Bool_t ContainerMatchTClonesArray(TClass *newClass)
01026 {
01027
01028
01029
01030 return newClass->GetCollectionProxy()
01031 && newClass->GetCollectionProxy()->GetValueClass()
01032 && !newClass->GetCollectionProxy()->HasPointers();
01033 }
01034
01035 Bool_t CollectionMatch(const TClass *oldClass, const TClass* newClass)
01036 {
01037
01038
01039
01040 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
01041 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
01042
01043 TClass *oldContent = oldProxy->GetValueClass();
01044 TClass *newContent = newProxy->GetValueClass();
01045
01046 Bool_t contentMatch = kFALSE;
01047 if (oldContent) {
01048 if (oldContent == newContent) {
01049 contentMatch = kTRUE;
01050 } else if (newContent) {
01051 TString oldFlatContent( TMakeProject::UpdateAssociativeToVector(oldContent->GetName()) );
01052 TString newFlatContent( TMakeProject::UpdateAssociativeToVector(newContent->GetName()) );
01053 contentMatch = kTRUE;
01054 } else {
01055 contentMatch = kFALSE;
01056 }
01057 } else {
01058 contentMatch = (newContent==0);
01059 }
01060
01061 if (contentMatch) {
01062 if ((oldContent==0 && oldProxy->GetType() == newProxy->GetType())
01063 ||(oldContent && oldProxy->HasPointers() == newProxy->HasPointers())) {
01064
01065 return kTRUE;
01066 }
01067 }
01068 return kFALSE;
01069 }
01070
01071 Bool_t CollectionMatchFloat16(const TClass *oldClass, const TClass* newClass)
01072 {
01073
01074
01075
01076 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
01077 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
01078
01079 if (oldProxy->GetValueClass() == 0 && newProxy->GetValueClass() == 0
01080 && (oldProxy->GetType() == kFloat_t || oldProxy->GetType() == kFloat16_t)
01081 && (newProxy->GetType() == kFloat_t || newProxy->GetType() == kFloat16_t )) {
01082
01083 return (TClassEdit::IsSTLCont(oldClass->GetName()) == TClassEdit::IsSTLCont(newClass->GetName()));
01084 }
01085 return kFALSE;
01086 }
01087
01088 Bool_t CollectionMatchDouble32(const TClass *oldClass, const TClass* newClass)
01089 {
01090
01091
01092
01093 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
01094 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
01095
01096 if (oldProxy->GetValueClass() == 0 && newProxy->GetValueClass() == 0
01097 && (oldProxy->GetType() == kDouble_t || oldProxy->GetType() == kDouble32_t)
01098 && (newProxy->GetType() == kDouble_t || newProxy->GetType() == kDouble32_t )) {
01099
01100 return (TClassEdit::IsSTLCont(oldClass->GetName()) == TClassEdit::IsSTLCont(newClass->GetName()));
01101 }
01102 return kFALSE;
01103 }
01104
01105 Bool_t CollectionMatchLong64(const TClass *oldClass, const TClass* newClass)
01106 {
01107
01108
01109
01110 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
01111 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
01112
01113 if (oldProxy->GetValueClass() == 0 && newProxy->GetValueClass() == 0
01114 && (oldProxy->GetType() == kLong_t || oldProxy->GetType() == kLong64_t)
01115 && (newProxy->GetType() == kLong_t || newProxy->GetType() == kLong64_t )) {
01116
01117 return (TClassEdit::IsSTLCont(oldClass->GetName()) == TClassEdit::IsSTLCont(newClass->GetName()));
01118 }
01119 return kFALSE;
01120 }
01121
01122 Bool_t CollectionMatchULong64(const TClass *oldClass, const TClass* newClass)
01123 {
01124
01125
01126
01127 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
01128 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
01129
01130 if (oldProxy->GetValueClass() == 0 && newProxy->GetValueClass() == 0
01131 && (oldProxy->GetType() == kULong_t || oldProxy->GetType() == kULong64_t)
01132 && (newProxy->GetType() == kULong_t || newProxy->GetType() == kULong64_t )) {
01133
01134 return (TClassEdit::IsSTLCont(oldClass->GetName()) == TClassEdit::IsSTLCont(newClass->GetName()));
01135 }
01136 return kFALSE;
01137 }
01138 }
01139
01140
01141 void TStreamerInfo::BuildOld()
01142 {
01143
01144
01145 R__LOCKGUARD(gCINTMutex);
01146
01147 if (gDebug > 0) {
01148 printf("\n====>Rebuilding TStreamerInfo for class: %s, version: %d\n", GetName(), fClassVersion);
01149 }
01150
01151 Bool_t wasCompiled = IsCompiled();
01152
01153
01154 fIsBuilt = kTRUE;
01155
01156 if (fClass->GetClassVersion() == fClassVersion) {
01157 fClass->BuildRealData();
01158 }
01159 else {
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180 fClass->GetStreamerInfo();
01181 }
01182
01183 TIter next(fElements);
01184 TStreamerElement* element;
01185 Int_t offset = 0;
01186 TMemberStreamer* streamer = 0;
01187
01188 Int_t sp = sizeof(void*);
01189 #if defined(R__SGI64)
01190 sp = 8;
01191 #endif
01192
01193 int nBaze = 0;
01194
01195 if (fClass->GetCollectionProxy() && (fElements->GetEntries() == 1) && !strcmp(fElements->At(0)->GetName(), "This")) {
01196 element = (TStreamerElement*)next();
01197 element->SetNewType( element->GetType() );
01198 element->SetNewClass( fClass );
01199 }
01200
01201 TClass *allocClass = 0;
01202 TStreamerInfo *infoalloc = 0;
01203
01204
01205
01206
01207 const ROOT::TSchemaMatch* rules = 0;
01208 const ROOT::TSchemaRuleSet* ruleSet = fClass->GetSchemaRules();
01209
01210 rules = (ruleSet ? ruleSet->FindRules( GetName(), fOnFileClassVersion, fCheckSum ) : 0);
01211
01212 Bool_t shouldHaveInfoLoc = fClass->TestBit(TClass::kIsEmulation) && !TClassEdit::IsStdClass(fClass->GetName());
01213 Int_t virtualInfoLocAlloc = 0;
01214 fNVirtualInfoLoc = 0;
01215 delete [] fVirtualInfoLoc;
01216 fVirtualInfoLoc = 0;
01217
01218 while ((element = (TStreamerElement*) next())) {
01219 if (element->IsA()==TStreamerArtificial::Class()
01220 || element->TestBit(TStreamerElement::kCache) )
01221 {
01222
01223
01224
01225
01226
01227 continue;
01228 };
01229
01230 element->SetNewType(element->GetType());
01231 element->Init();
01232 if (element->IsBase()) {
01233
01234
01235
01236 if (element->IsA() == TStreamerBase::Class()) {
01237 TStreamerBase* base = (TStreamerBase*) element;
01238 #if defined(PROPER_IMPLEMEMANTION_OF_BASE_CLASS_RENAMING)
01239 TClass* baseclass = fClass->GetBaseClass( base->GetName() );
01240 #else
01241
01242
01243
01244 TClass* baseclass = base->GetClassPointer();
01245 #endif
01246
01247
01248
01249
01250 if( !baseclass && !fClass->TestBit( TClass::kIsEmulation ) ) {
01251 const ROOT::TSchemaRule* rule = (rules ? rules->GetRuleWithSource( base->GetName() ) : 0);
01252
01253
01254
01255
01256 if( !rule ) {
01257 Error("BuildOld", "Could not find base class: %s for %s and could not find any matching rename rule\n", base->GetName(), GetName());
01258 continue;
01259 }
01260
01261
01262
01263
01264 const TObjArray* targets = rule->GetTarget();
01265 if( !targets ) {
01266 Error("BuildOld", "Could not find base class: %s for %s, renaming rule was found but is malformed\n", base->GetName(), GetName());
01267 }
01268 TString newBaseClass = ((TObjString*)targets->At(0))->GetString();
01269 baseclass = TClass::GetClass( newBaseClass );
01270 base->SetNewBaseClass( baseclass );
01271 }
01272
01273
01274
01275 else if( !baseclass ) {
01276 baseclass = base->GetClassPointer();
01277 if (!baseclass) {
01278 Warning("BuildOld", "Missing base class: %s skipped", base->GetName());
01279
01280 baseclass = new TClass(element->GetName(), 1, 0, 0, -1, -1);
01281 element->Update(0, baseclass);
01282 }
01283 }
01284 baseclass->BuildRealData();
01285
01286
01287
01288 Int_t version = base->GetBaseVersion();
01289 TStreamerInfo* infobase = (TStreamerInfo*)baseclass->GetStreamerInfo(version);
01290 if (infobase->GetTypes() == 0) {
01291 infobase->BuildOld();
01292 }
01293 Int_t baseOffset = fClass->GetBaseClassOffset(baseclass);
01294
01295 if (shouldHaveInfoLoc && baseclass->TestBit(TClass::kIsEmulation) ) {
01296 if ( (fNVirtualInfoLoc + infobase->fNVirtualInfoLoc) > virtualInfoLocAlloc ) {
01297 ULong_t *store = fVirtualInfoLoc;
01298 virtualInfoLocAlloc = 16 * ( (fNVirtualInfoLoc + infobase->fNVirtualInfoLoc) / 16 + 1);
01299 fVirtualInfoLoc = new ULong_t[virtualInfoLocAlloc];
01300 if (store) {
01301 memcpy(fVirtualInfoLoc, store, sizeof(ULong_t)*fNVirtualInfoLoc);
01302 delete [] store;
01303 }
01304 }
01305 for (int nloc = 0; nloc < infobase->fNVirtualInfoLoc; ++nloc) {
01306 fVirtualInfoLoc[ fNVirtualInfoLoc + nloc ] = baseOffset + infobase->fVirtualInfoLoc[nloc];
01307 }
01308 fNVirtualInfoLoc += infobase->fNVirtualInfoLoc;
01309 }
01310
01311
01312 if (baseOffset < 0) {
01313 baseOffset = 0;
01314 }
01315 element->SetOffset(baseOffset);
01316 offset += baseclass->Size();
01317
01318 continue;
01319 } else {
01320
01321 nBaze++;
01322 TList* listOfBases = fClass->GetListOfBases();
01323 Int_t baseOffset = -1;
01324 Int_t asize = 0;
01325 if (listOfBases) {
01326
01327
01328 TBaseClass* bc = 0;
01329 TIter nextBC(fClass->GetListOfBases());
01330 while ((bc = (TBaseClass*) nextBC())) {
01331 if (strchr(bc->GetName(), '<') || !strcmp(bc->GetName(),"string")) {
01332 TString bcName(TClassEdit::ShortType(bc->GetName(), TClassEdit::kDropStlDefault).c_str());
01333 TString elName(TClassEdit::ShortType(element->GetTypeName(), TClassEdit::kDropStlDefault).c_str());
01334 if (bcName == elName) {
01335 break;
01336 }
01337 }
01338 }
01339
01340 if (!bc) {
01341 Error("BuildOld", "Could not find STL base class: %s for %s\n", element->GetName(), GetName());
01342 continue;
01343 }
01344 baseOffset = bc->GetDelta();
01345 asize = bc->GetClassPointer()->Size();
01346
01347 } else if (fClass->TestBit( TClass::kIsEmulation )) {
01348
01349
01350 TStreamerInfo* newInfo = (TStreamerInfo*) fClass->GetStreamerInfos()->At(fClass->GetClassVersion());
01351 if (newInfo == this) {
01352 baseOffset = offset;
01353 asize = element->GetSize();
01354 } else if (newInfo) {
01355 TIter newElems( newInfo->GetElements() );
01356 TStreamerElement *newElement;
01357 while( (newElement = (TStreamerElement*)newElems()) ) {
01358 const char *newElName = newElement->GetName();
01359 if (newElement->IsBase() && (strchr(newElName,'<') || !strcmp(newElName,"string")) ) {
01360 TString bcName(TClassEdit::ShortType(newElName, TClassEdit::kDropStlDefault).c_str());
01361 TString elName(TClassEdit::ShortType(element->GetTypeName(), TClassEdit::kDropStlDefault).c_str());
01362 if (bcName == elName) {
01363 break;
01364 }
01365 }
01366 }
01367 if (!newElement) {
01368 Error("BuildOld", "Could not find STL base class: %s for %s\n", element->GetName(), GetName());
01369 continue;
01370 }
01371 baseOffset = newElement->GetOffset();
01372 asize = newElement->GetSize();
01373 }
01374 }
01375 if (baseOffset == -1) {
01376 TClass* cb = element->GetClassPointer();
01377 if (!cb) {
01378 element->SetNewType(-1);
01379 continue;
01380 }
01381 asize = cb->Size();
01382 baseOffset = fClass->GetBaseClassOffset(cb);
01383 }
01384
01385
01386 if (baseOffset < 0) {
01387 element->SetNewType(-1);
01388 continue;
01389 }
01390 element->SetOffset(baseOffset);
01391 offset += asize;
01392 continue;
01393 }
01394 }
01395
01396
01397 if (shouldHaveInfoLoc && fNVirtualInfoLoc==0) {
01398 fNVirtualInfoLoc = 1;
01399 fVirtualInfoLoc = new ULong_t[1];
01400 fVirtualInfoLoc[0] = offset;
01401 offset += sizeof(TStreamerInfo*);
01402 }
01403
01404 TDataMember* dm = 0;
01405
01406
01407 if (fClass->GetDeclFileLine() < 0) {
01408
01409
01410
01411
01412
01413 streamer = 0;
01414 element->Init(this);
01415 } else {
01416
01417
01418
01419 dm = (TDataMember*) fClass->GetListOfDataMembers()->FindObject(element->GetName());
01420 if (dm && dm->IsPersistent()) {
01421 fClass->BuildRealData();
01422 streamer = 0;
01423 offset = GetDataMemberOffset(dm, streamer);
01424 element->SetOffset(offset);
01425 element->Init(this);
01426 element->SetStreamer(streamer);
01427 int narr = element->GetArrayLength();
01428 if (!narr) {
01429 narr = 1;
01430 }
01431 int dsize = dm->GetUnitSize();
01432 element->SetSize(dsize*narr);
01433 } else {
01434
01435 TRealData* rd = fClass->GetRealData(element->GetName());
01436 if (rd && rd->GetDataMember()) {
01437 element->SetOffset(rd->GetThisOffset());
01438 element->Init(this);
01439 dm = rd->GetDataMember();
01440 int narr = element->GetArrayLength();
01441 if (!narr) {
01442 narr = 1;
01443 }
01444 int dsize = dm->GetUnitSize();
01445 element->SetSize(dsize*narr);
01446 }
01447 }
01448 }
01449
01450
01451 Int_t newType = kNoType_t;
01452 TClassRef newClass;
01453
01454 if (dm && dm->IsPersistent()) {
01455 if (dm->GetDataType()) {
01456 Bool_t isPointer = dm->IsaPointer();
01457 Bool_t isArray = element->GetArrayLength() >= 1;
01458 Bool_t hasCount = element->HasCounter();
01459 newType = dm->GetDataType()->GetType();
01460 if ((newType == kChar) && isPointer && !isArray && !hasCount) {
01461 newType = kCharStar;
01462 } else if (isPointer) {
01463 newType += kOffsetP;
01464 } else if (isArray) {
01465 newType += kOffsetL;
01466 }
01467 }
01468 if (newType == 0) {
01469 newClass = TClass::GetClass(dm->GetTypeName());
01470 }
01471 } else {
01472
01473 if (!fClass->IsLoaded()) {
01474 TStreamerInfo* newInfo = (TStreamerInfo*) fClass->GetStreamerInfos()->At(fClass->GetClassVersion());
01475 if (newInfo && (newInfo != this)) {
01476 TStreamerElement* newElems = (TStreamerElement*) newInfo->GetElements()->FindObject(element->GetName());
01477 newClass = newElems ? newElems->GetClassPointer() : 0;
01478 if (newClass == 0) {
01479 newType = newElems ? newElems->GetType() : kNoType_t;
01480 if (!(newType < kObject)) {
01481
01482 newType = kNoType_t;
01483 }
01484 }
01485 } else {
01486 newClass = element->GetClassPointer();
01487 if (newClass.GetClass() == 0) {
01488 newType = element->GetType();
01489 if (!(newType < kObject)) {
01490
01491 newType = kNoType_t;
01492 }
01493 }
01494 }
01495 }
01496 }
01497
01498 if (newType) {
01499
01500 if (element->GetType() != newType) {
01501 element->SetNewType(newType);
01502 if (gDebug > 0) {
01503 Info("BuildOld", "element: %s %s::%s has new type: %s/%d", element->GetTypeName(), GetName(), element->GetName(), dm ? dm->GetFullTypeName() : TDataType::GetTypeName((EDataType)newType), newType);
01504 }
01505 }
01506 } else if (newClass.GetClass()) {
01507
01508
01509
01510 newClass.Reset();
01511 TClass* oldClass = TClass::GetClass(TClassEdit::ShortType(element->GetTypeName(), TClassEdit::kDropTrailStar).c_str());
01512 if (oldClass == newClass.GetClass()) {
01513
01514 } else if (ClassWasMovedToNamespace(oldClass, newClass.GetClass())) {
01515 Int_t oldv;
01516 if (0 != (oldv = ImportStreamerInfo(oldClass, newClass.GetClass()))) {
01517 Warning("BuildOld", "Can not properly load the TStreamerInfo from %s into %s due to a conflict for the class version %d", oldClass->GetName(), newClass->GetName(), oldv);
01518 } else {
01519 element->SetTypeName(newClass->GetName());
01520 if (gDebug > 0) {
01521 Warning("BuildOld", "element: %s::%s %s has new type %s", GetName(), element->GetTypeName(), element->GetName(), newClass->GetName());
01522 }
01523 }
01524 } else if (oldClass == TClonesArray::Class()) {
01525 if (ContainerMatchTClonesArray(newClass.GetClass())) {
01526 Int_t elemType = element->GetType();
01527 Bool_t isPrealloc = (elemType == kObjectp) || (elemType == kAnyp) || (elemType == (kObjectp + kOffsetL)) || (elemType == (kAnyp + kOffsetL));
01528 element->Update(oldClass, newClass.GetClass());
01529 TVirtualCollectionProxy *cp = newClass->GetCollectionProxy();
01530 TConvertClonesArrayToProxy *ms = new TConvertClonesArrayToProxy(cp, element->IsaPointer(), isPrealloc);
01531 element->SetStreamer(ms);
01532
01533
01534
01535
01536 if (element->GetType() == kObject) {
01537 element->SetNewType(kAny);
01538 element->SetType(kAny);
01539 }
01540 if (gDebug > 0) {
01541 Warning("BuildOld","element: %s::%s %s has new type %s", GetName(), element->GetTypeName(), element->GetName(), newClass->GetName());
01542 }
01543 } else {
01544 element->SetNewType(-2);
01545 }
01546 } else if (oldClass && oldClass->GetCollectionProxy() && newClass->GetCollectionProxy()) {
01547 if (CollectionMatch(oldClass, newClass)) {
01548 Int_t oldkind = TMath::Abs(TClassEdit::IsSTLCont( oldClass->GetName() ));
01549 Int_t newkind = TMath::Abs(TClassEdit::IsSTLCont( newClass->GetName() ));
01550
01551 if ( (oldkind==TClassEdit::kMap || oldkind==TClassEdit::kMultiMap) &&
01552 (newkind!=TClassEdit::kMap && newkind!=TClassEdit::kMultiMap) ) {
01553
01554 Int_t elemType = element->GetType();
01555 Bool_t isPrealloc = (elemType == kObjectp) || (elemType == kAnyp) || (elemType == (kObjectp + kOffsetL)) || (elemType == (kAnyp + kOffsetL));
01556
01557 TClassStreamer *streamer2 = newClass->GetStreamer();
01558 if (streamer2) {
01559 TConvertMapToProxy *ms = new TConvertMapToProxy(streamer2, element->IsaPointer(), isPrealloc);
01560 if (ms && ms->IsValid()) {
01561 element->SetStreamer(ms);
01562 switch( element->GetType() ) {
01563
01564 case TStreamerInfo::kSTLp:
01565 case TStreamerInfo::kSTLp + TStreamerInfo::kOffsetL:
01566 element->SetNewType(-2);
01567 break;
01568 case TStreamerInfo::kSTL:
01569 case TStreamerInfo::kSTL + TStreamerInfo::kOffsetL:
01570 break;
01571 }
01572 } else {
01573 delete ms;
01574 }
01575 }
01576 element->Update(oldClass, newClass.GetClass());
01577
01578 } else if ( (newkind==TClassEdit::kMap || newkind==TClassEdit::kMultiMap) &&
01579 (oldkind!=TClassEdit::kMap && oldkind!=TClassEdit::kMultiMap) ) {
01580 element->SetNewType(-2);
01581 } else {
01582 element->Update(oldClass, newClass.GetClass());
01583 }
01584
01585 if (gDebug > 0) {
01586 Warning("BuildOld","element: %s::%s %s has new type %s", GetName(), element->GetTypeName(), element->GetName(), newClass->GetName());
01587 }
01588 } else if (CollectionMatchFloat16(oldClass,newClass)) {
01589
01590 } else if (CollectionMatchDouble32(oldClass,newClass)) {
01591
01592 } else if (CollectionMatchLong64(oldClass,newClass)) {
01593
01594 element->Update(oldClass, newClass.GetClass());
01595 } else if (CollectionMatchULong64(oldClass,newClass)) {
01596
01597 element->Update(oldClass, newClass.GetClass());
01598 } else {
01599 element->SetNewType(-2);
01600 }
01601
01602 } else if(oldClass &&
01603 newClass.GetClass() &&
01604 newClass->GetSchemaRules() &&
01605 newClass->GetSchemaRules()->HasRuleWithSourceClass( oldClass->GetName() ) ) {
01606
01607
01608
01609 element->SetNewClass( newClass );
01610 } else {
01611 element->SetNewType(-2);
01612 }
01613 } else {
01614 element->SetNewType(-1);
01615 offset = kMissing;
01616 element->SetOffset(kMissing);
01617 }
01618
01619 if (offset != kMissing && fClass->GetDeclFileLine() < 0) {
01620
01621
01622
01623 Int_t asize = element->GetSize();
01624
01625 if ((offset % sp) != 0) {
01626 offset = offset - (offset % sp) + sp;
01627 }
01628 element->SetOffset(offset);
01629 offset += asize;
01630 }
01631
01632 if ( !wasCompiled && rules && rules->HasRuleWithSource( element->GetName(), kTRUE ) ) {
01633
01634 if (allocClass == 0) {
01635 infoalloc = (TStreamerInfo *)Clone(TString::Format("%s@@%d",GetName(),GetOnFileClassVersion()));
01636 infoalloc->BuildCheck();
01637 infoalloc->BuildOld();
01638 allocClass = infoalloc->GetClass();
01639 }
01640
01641
01642 if (element->GetNewType()>0
01643 && !rules->HasRuleWithTarget( element->GetName(), kTRUE ) )
01644 {
01645 TStreamerElement *copy = (TStreamerElement*)element->Clone();
01646 R__TObjArray_InsertBefore( fElements, copy, element );
01647 next();
01648 copy->SetBit(TStreamerElement::kRepeat);
01649 element = copy;
01650
01651
01652 }
01653 element->SetBit(TStreamerElement::kCache);
01654 element->SetNewType( element->GetType() );
01655 element->SetOffset(infoalloc->GetOffset(element->GetName()));
01656 }
01657
01658 if (element->GetNewType() == -2) {
01659 Warning("BuildOld", "Cannot convert %s::%s from type:%s to type:%s, skip element", GetName(), element->GetName(), element->GetTypeName(), newClass->GetName());
01660 }
01661 }
01662
01663
01664
01665 if (shouldHaveInfoLoc && fNVirtualInfoLoc==0) {
01666 fNVirtualInfoLoc = 1;
01667 fVirtualInfoLoc = new ULong_t[1];
01668 fVirtualInfoLoc[0] = offset;
01669 offset += sizeof(TStreamerInfo*);
01670 }
01671
01672
01673 if ((fOldVersion <= 2) && nBaze) {
01674 SetBit(kRecovered);
01675 TObjArray& arr = *fElements;
01676 TObjArray tai(nBaze);
01677 int narr = arr.GetLast() + 1;
01678 int iel;
01679 int jel = 0;
01680 int kel = 0;
01681 for (iel = 0; iel < narr; ++iel) {
01682 element = (TStreamerElement*) arr[iel];
01683 if (element->IsBase() && (element->IsA() != TStreamerBase::Class())) {
01684 tai[kel++] = element;
01685 } else {
01686 arr[jel++] = element;
01687 }
01688 }
01689 for (kel = 0; jel < narr;) {
01690 arr[jel++] = tai[kel++];
01691 }
01692 }
01693
01694
01695 if (!wasCompiled) InsertArtificialElements(rules);
01696
01697 if (!wasCompiled && allocClass) {
01698
01699 TStreamerElement *el = new TStreamerArtificial("@@alloc","", 0, TStreamerInfo::kCacheNew, allocClass->GetName());
01700 R__TObjArray_InsertAt( fElements, el, 0 );
01701
01702 el = new TStreamerArtificial("@@dealloc","", 0, TStreamerInfo::kCacheDelete, allocClass->GetName());
01703 fElements->Add( el );
01704 }
01705
01706 Compile();
01707 delete rules;
01708 }
01709
01710
01711 void TStreamerInfo::Clear(Option_t *option)
01712 {
01713
01714
01715
01716 TString opt = option;
01717 opt.ToLower();
01718
01719 if (opt.Contains("build")) {
01720 delete [] fType; fType = 0;
01721 delete [] fNewType; fNewType = 0;
01722 delete [] fOffset; fOffset = 0;
01723 delete [] fLength; fLength = 0;
01724 delete [] fElem; fElem = 0;
01725 delete [] fMethod; fMethod = 0;
01726 delete [] fComp; fComp = 0;
01727 fNdata = 0;
01728 fSize = 0;
01729 ResetBit(kIsCompiled);
01730
01731 if (fReadObjectWise) fReadObjectWise->fActions.clear();
01732 if (fReadMemberWise) fReadMemberWise->fActions.clear();
01733 }
01734 }
01735
01736 namespace {
01737
01738
01739
01740 class TMemberInfo {
01741 public:
01742 TString fName;
01743 TString fClassName;
01744 TString fComment;
01745 void SetName(const char *name) {
01746 fName = name;
01747 }
01748 void SetClassName(const char *name) {
01749 fClassName = TClassEdit::ShortType( name, TClassEdit::kDropStlDefault );
01750 }
01751 void SetComment(const char *title) {
01752 const char *left = strstr(title,"[");
01753 if (left) {
01754 const char *right = strstr(left,"]");
01755 if (right) {
01756 ++left;
01757 fComment.Append(left,right-left);
01758 }
01759 }
01760 }
01761 void Clear() {
01762 fName.Clear();
01763 fClassName.Clear();
01764 fComment.Clear();
01765 }
01766
01767
01768
01769
01770
01771
01772
01773
01774 Bool_t operator!=(const TMemberInfo &other) {
01775 if (fName != other.fName) return kTRUE;
01776 if (fClassName != other.fClassName) {
01777 if ( (fClassName == "long" && (other.fClassName == "long long" || other.fClassName == "Long64_t"))
01778 || ( (fClassName == "long long" || fClassName == "Long64_t") && other.fClassName == "long") ) {
01779
01780 } else if ( (fClassName == "unsigned long" && (other.fClassName == "unsigned long long" || other.fClassName == "ULong64_t"))
01781 || ( (fClassName == "unsigned long long" || fClassName == "ULong64_t") && other.fClassName == "unsigned long") ) {
01782
01783 } else {
01784 return kTRUE;
01785 }
01786 }
01787 return fComment != other.fComment;
01788 }
01789 };
01790 }
01791
01792
01793 void TStreamerInfo::CallShowMembers(void* obj, TMemberInspector &insp) const
01794 {
01795
01796
01797 TIter next(fElements);
01798 TStreamerElement* element = (TStreamerElement*) next();
01799
01800 TString elementName;
01801
01802 for (; element; element = (TStreamerElement*) next()) {
01803
01804
01805 if (element->GetOffset() == kMissing) {
01806 continue;
01807 }
01808
01809 char* eaddr = ((char*)obj) + element->GetOffset();
01810
01811 if (element->IsBase()) {
01812
01813 } else if (element->IsaPointer()) {
01814 elementName.Form("*%s",element->GetFullName());
01815 insp.Inspect(fClass, insp.GetParent(), elementName.Data(), eaddr);
01816 } else {
01817 insp.Inspect(fClass, insp.GetParent(), element->GetFullName(), eaddr);
01818 Int_t etype = element->GetType();
01819 switch(etype) {
01820 case kObject:
01821 case kAny:
01822 case kTObject:
01823 case kTString:
01824 case kTNamed:
01825 case kSTL:
01826 {
01827 TClass *ecl = element->GetClassPointer();
01828 if (ecl && (fClass!=ecl )) {
01829 insp.InspectMember(ecl, eaddr, TString(element->GetName()) + ".");
01830 }
01831 break;
01832 }
01833 }
01834 }
01835 }
01836
01837
01838 next.Reset();
01839 element = (TStreamerElement*) next();
01840 for (; element; element = (TStreamerElement*) next()) {
01841 if (element->IsBase()) {
01842
01843 if (element->GetOffset() == kMissing) {
01844 continue;
01845 }
01846
01847 char* eaddr = ((char*)obj) + element->GetOffset();
01848
01849 TClass *ecl = element->GetClassPointer();
01850 if (ecl) {
01851 ecl->CallShowMembers(eaddr, insp);
01852 }
01853 }
01854 }
01855 }
01856
01857
01858 TObject *TStreamerInfo::Clone(const char *newname) const
01859 {
01860
01861
01862
01863 TStreamerInfo *newinfo = (TStreamerInfo*)TNamed::Clone(newname);
01864 if (newname && newname[0] && fName != newname) {
01865 TObjArray *newelems = newinfo->GetElements();
01866 Int_t ndata = newelems->GetEntries();
01867 for(Int_t i = 0; i < ndata; ++i) {
01868 TObject *element = newelems->UncheckedAt(i);
01869 if (element->IsA() == TStreamerLoop::Class()) {
01870 TStreamerLoop *eloop = (TStreamerLoop*)element;
01871 if (fName == eloop->GetCountClass()) {
01872 eloop->SetCountClass(newname);
01873 eloop->Init();
01874 }
01875 } else if (element->IsA() == TStreamerBasicPointer::Class()) {
01876 TStreamerBasicPointer *eptr = (TStreamerBasicPointer*)element;
01877 if (fName == eptr->GetCountClass()) {
01878 eptr->SetCountClass(newname);
01879 eptr->Init();
01880 }
01881 }
01882 }
01883 }
01884 return newinfo;
01885 }
01886
01887
01888 Bool_t TStreamerInfo::CompareContent(TClass *cl, TVirtualStreamerInfo *info, Bool_t warn, Bool_t complete)
01889 {
01890
01891
01892
01893
01894
01895
01896 Bool_t result = kTRUE;
01897 R__ASSERT( (cl==0 || info==0) && (cl!=0 || info!=0) );
01898
01899 TString name;
01900 TString type;
01901 TStreamerElement *el;
01902 TStreamerElement *infoel;
01903
01904 TIter next(GetElements());
01905 TIter infonext((TList*)0);
01906 TIter basenext((TList*)0);
01907 TIter membernext((TList*)0);
01908 if (info) {
01909 infonext = info->GetElements();
01910 }
01911 if (cl) {
01912 TList *tlb = cl->GetListOfBases();
01913 if (tlb) {
01914 basenext = tlb;
01915 }
01916 tlb = cl->GetListOfDataMembers();
01917 if (tlb) {
01918 membernext = tlb;
01919 }
01920 }
01921
01922
01923 Bool_t done = kFALSE;
01924 TString localClass;
01925 TString otherClass;
01926 while(!done) {
01927 localClass.Clear();
01928 otherClass.Clear();
01929 el = (TStreamerElement*)next();
01930 if (el && el->IsBase()) {
01931 localClass = el->GetName();
01932 } else {
01933 el = 0;
01934 }
01935 if (cl) {
01936 TBaseClass *tbc = (TBaseClass*)basenext();
01937 if (tbc) {
01938 otherClass = tbc->GetName();
01939 } else if (el==0) {
01940 done = kTRUE;
01941 break;
01942 }
01943 } else {
01944 infoel = (TStreamerElement*)infonext();
01945 if (infoel && infoel->IsBase()) {
01946 otherClass = infoel->GetName();
01947 } else if (el==0) {
01948 done = kTRUE;
01949 break;
01950 }
01951 }
01952
01953 if (localClass != otherClass) {
01954 if (warn) {
01955 if (el==0) {
01956 Warning("CompareContent",
01957 "The in-memory layout version %d for class '%s' has a base class (%s) that the on-file layout version %d does not have.",
01958 GetClassVersion(), GetName(), otherClass.Data(), GetClassVersion());
01959 } else if (otherClass.Length()==0) {
01960 Warning("CompareContent",
01961 "The on-file layout version %d for class '%s' has a base class (%s) that the in-memory layout version %d does not have",
01962 GetClassVersion(), GetName(), localClass.Data(), GetClassVersion());
01963 } else {
01964 Warning("CompareContent",
01965 "One base class of the on-file layout version %d and of the in memory layout version %d for '%s' is different: '%s' vs '%s'",
01966 GetClassVersion(), GetClassVersion(), GetName(), localClass.Data(), otherClass.Data());
01967 }
01968 }
01969 if (!complete) return kFALSE;
01970 result = result && kFALSE;
01971 }
01972 }
01973 if (!result && !complete) {
01974 return result;
01975 }
01976
01977 done = kFALSE;
01978 next.Reset();
01979 infonext.Reset();
01980
01981 TMemberInfo local;
01982 TMemberInfo other;
01983 UInt_t idx = 0;
01984 while(!done) {
01985 local.Clear();
01986 other.Clear();
01987 el = (TStreamerElement*)next();
01988 while (el && (el->IsBase() || el->IsA() == TStreamerArtificial::Class())) {
01989 el = (TStreamerElement*)next();
01990 ++idx;
01991 }
01992 if (el) {
01993 local.SetName( el->GetName() );
01994 local.SetClassName( el->GetTypeName() );
01995 local.SetComment( el->GetTitle() );
01996 }
01997 if (cl) {
01998 TDataMember *tdm = (TDataMember*)membernext();
01999 while(tdm && ( (!tdm->IsPersistent()) || (tdm->Property()&kIsStatic) || (el && local.fName != tdm->GetName()) )) {
02000 tdm = (TDataMember*)membernext();
02001 }
02002 if (tdm) {
02003 other.SetName( tdm->GetName() );
02004 other.SetClassName( tdm->GetFullTypeName() );
02005 other.SetComment( tdm->GetTitle() );
02006 } else if (el==0) {
02007 done = kTRUE;
02008 break;
02009 }
02010 } else {
02011 infoel = (TStreamerElement*)infonext();
02012 while (infoel && (infoel->IsBase() || infoel->IsA() == TStreamerArtificial::Class())) {
02013 infoel = (TStreamerElement*)infonext();
02014 }
02015 if (infoel) {
02016 other.SetName( infoel->GetName() );
02017 other.SetClassName( infoel->GetTypeName() );
02018 other.SetComment( infoel->GetTitle() );
02019 } else if (el==0) {
02020 done = kTRUE;
02021 break;
02022 }
02023 }
02024 if (local!=other) {
02025 if (warn) {
02026 if (!el) {
02027 Warning("CompareContent","The following data member of\nthe on-file layout version %d of class '%s' is missing from \nthe in-memory layout version %d:\n"
02028 " %s %s; //%s"
02029 ,GetClassVersion(), GetName(), GetClassVersion()
02030 ,other.fClassName.Data(),other.fName.Data(),other.fComment.Data());
02031
02032 } else if (other.fName.Length()==0) {
02033 Warning("CompareContent","The following data member of\nthe in-memory layout version %d of class '%s' is missing from \nthe on-file layout version %d:\n"
02034 " %s %s; //%s"
02035 ,GetClassVersion(), GetName(), GetClassVersion()
02036 ,local.fClassName.Data(),local.fName.Data(),local.fComment.Data());
02037 } else {
02038 Warning("CompareContent","The following data member of\nthe on-file layout version %d of class '%s' differs from \nthe in-memory layout version %d:\n"
02039 " %s %s; //%s\n"
02040 "vs\n"
02041 " %s %s; //%s"
02042 ,GetClassVersion(), GetName(), GetClassVersion()
02043 ,local.fClassName.Data(),local.fName.Data(),local.fComment.Data()
02044 ,other.fClassName.Data(),other.fName.Data(),other.fComment.Data());
02045 }
02046 }
02047 result = result && kFALSE;
02048 if (!complete) return result;
02049 }
02050 ++idx;
02051 }
02052 return result;
02053 }
02054
02055
02056
02057 void TStreamerInfo::ComputeSize()
02058 {
02059
02060
02061 TStreamerElement *element = (TStreamerElement*)fElements->Last();
02062
02063
02064 fSize = element->GetOffset() + element->GetSize();
02065 if (fNVirtualInfoLoc > 0 && (fVirtualInfoLoc[0]+sizeof(TStreamerInfo*)) >= (ULong_t)fSize) {
02066 fSize = fVirtualInfoLoc[0] + sizeof(TStreamerInfo*);
02067 }
02068 }
02069
02070
02071 void TStreamerInfo::ForceWriteInfo(TFile* file, Bool_t force)
02072 {
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087 if (!file) {
02088 return;
02089 }
02090
02091 TArrayC* cindex = file->GetClassIndex();
02092
02093
02094
02095
02096
02097 if (
02098 (cindex->fArray[fNumber] && !force) ||
02099 (cindex->fArray[fNumber] > 1)
02100 ) {
02101 return;
02102 }
02103
02104
02105 static TClassRef string_classref("string");
02106 if (fClass == string_classref) {
02107 return;
02108 }
02109
02110
02111 if (fClass==0) {
02112
02113
02114 if (fElements && fElements->GetEntries()==1 && strcmp("This",fElements->UncheckedAt(0)->GetName())==0) {
02115
02116 return;
02117 }
02118 } else if (fClass->GetCollectionProxy()) {
02119 return;
02120 }
02121
02122
02123 cindex->fArray[fNumber] = 2;
02124
02125 cindex->fArray[0] = 1;
02126
02127
02128 TIter next(fElements);
02129 TStreamerElement* element = (TStreamerElement*) next();
02130 for (; element; element = (TStreamerElement*) next()) {
02131 TClass* cl = element->GetClassPointer();
02132 if (cl) {
02133 TVirtualStreamerInfo* si = 0;
02134 if (cl->Property() & kIsAbstract) {
02135
02136
02137
02138
02139 si = cl->GetCurrentStreamerInfo();
02140 } else {
02141 si = cl->GetStreamerInfo();
02142 }
02143 if (si) {
02144 si->ForceWriteInfo(file, force);
02145 }
02146 }
02147 }
02148 }
02149
02150
02151 TClass *TStreamerInfo::GetActualClass(const void *obj) const
02152 {
02153
02154
02155
02156
02157
02158
02159
02160 R__ASSERT(!fClass->IsLoaded());
02161
02162 if (fNVirtualInfoLoc != 0) {
02163 TStreamerInfo *allocator = *(TStreamerInfo**)( (const char*)obj + fVirtualInfoLoc[0] );
02164 if (allocator) return allocator->GetClass();
02165 }
02166 return (TClass*)fClass;
02167 }
02168
02169
02170 UInt_t TStreamerInfo::GetCheckSum(UInt_t code) const
02171 {
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189 UInt_t id = 0;
02190
02191 int il;
02192 TString name = GetName();
02193 TString type;
02194 il = name.Length();
02195 for (int i=0; i<il; i++) id = id*3+name[i];
02196
02197 TIter next(GetElements());
02198 TStreamerElement *el;
02199 while ( (el=(TStreamerElement*)next()) ) {
02200 if (el->IsBase()) {
02201 name = el->GetName();
02202 il = name.Length();
02203 for (int i=0; i<il; i++) id = id*3+name[i];
02204 }
02205 }
02206
02207 next.Reset();
02208 while ( (el=(TStreamerElement*)next()) ) {
02209 if (el->IsBase()) continue;
02210
02211
02212
02213 Bool_t isenum = kFALSE;
02214 if ( el->GetType()==3 && gROOT->GetType(el->GetTypeName())==0) {
02215
02216
02217 isenum = kTRUE;
02218 }
02219 if ( (code != 1) && isenum) id = id*3 + 1;
02220
02221 name = el->GetName(); il = name.Length();
02222
02223 int i;
02224 for (i=0; i<il; i++) id = id*3+name[i];
02225
02226 type = el->GetTypeName();
02227 if (TClassEdit::IsSTLCont(type)) {
02228 type = TClassEdit::ShortType( type, TClassEdit::kDropStlDefault | TClassEdit::kLong64 );
02229 }
02230
02231 il = type.Length();
02232 for (i=0; i<il; i++) id = id*3+type[i];
02233
02234 int dim = el->GetArrayDim();
02235 if (dim) {
02236 for (i=0;i<dim;i++) id = id*3+el->GetMaxIndex(i);
02237 }
02238
02239
02240 if (code != 2) {
02241 const char *left = strstr(el->GetTitle(),"[");
02242 if (left) {
02243 const char *right = strstr(left,"]");
02244 if (right) {
02245 ++left;
02246 while (left != right) {
02247 id = id*3 + *left;
02248 ++left;
02249 }
02250 }
02251 }
02252 }
02253 }
02254 return id;
02255 }
02256
02257
02258 static void R__WriteConstructorBody(FILE *file, TIter &next)
02259 {
02260 TStreamerElement *element = 0;
02261 next.Reset();
02262 while ((element = (TStreamerElement*)next())) {
02263 if (element->GetType() == TVirtualStreamerInfo::kObjectp || element->GetType() == TVirtualStreamerInfo::kObjectP ||
02264 element->GetType() == TVirtualStreamerInfo::kAnyp || element->GetType() == TVirtualStreamerInfo::kAnyP ||
02265 element->GetType() == TVirtualStreamerInfo::kCharStar || element->GetType() == TVirtualStreamerInfo::kSTLp) {
02266 if(element->GetArrayLength() <= 1) {
02267 fprintf(file," %s = 0;\n",element->GetName());
02268 } else {
02269 fprintf(file," memset(%s,0,%d);\n",element->GetName(),element->GetSize());
02270 }
02271 }
02272 if (TVirtualStreamerInfo::kOffsetP <= element->GetType() && element->GetType() < TVirtualStreamerInfo::kObject ) {
02273 fprintf(file," %s = 0;\n",element->GetName());
02274 }
02275 }
02276 }
02277
02278
02279 static void R__WriteMoveConstructorBody(FILE *file, const TString &protoname, TIter &next)
02280 {
02281
02282
02283 TStreamerElement *element = 0;
02284 next.Reset();
02285 Bool_t atstart = kTRUE;
02286 while ((element = (TStreamerElement*)next())) {
02287 if (element->IsBase()) {
02288 if (atstart) { fprintf(file," : "); atstart = kFALSE; }
02289 else fprintf(file," , ");
02290 fprintf(file, "%s(const_cast<%s &>( rhs ))\n", element->GetName(),protoname.Data());
02291 } else {
02292 if (element->GetArrayLength() <= 1) {
02293 if (atstart) { fprintf(file," : "); atstart = kFALSE; }
02294 else fprintf(file," , ");
02295 fprintf(file, "%s(const_cast<%s &>( rhs ).%s)\n",element->GetName(),protoname.Data(),element->GetName());
02296 }
02297 }
02298 }
02299 fprintf(file,"{\n");
02300 fprintf(file," // This is NOT a copy constructor. This is actually a move constructor (for stl container's sake).\n");
02301 fprintf(file," // Use at your own risk!\n");
02302 fprintf(file," if (&rhs) {} // avoid warning about unused parameter\n");
02303 next.Reset();
02304 Bool_t defMod = kFALSE;
02305 while ((element = (TStreamerElement*)next())) {
02306 if (element->GetType() == TVirtualStreamerInfo::kObjectp || element->GetType() == TVirtualStreamerInfo::kObjectP||
02307 element->GetType() == TVirtualStreamerInfo::kAnyp || element->GetType() == TVirtualStreamerInfo::kAnyP
02308 || element->GetType() == TVirtualStreamerInfo::kAnyPnoVT)
02309 {
02310 if (!defMod) { fprintf(file," %s &modrhs = const_cast<%s &>( rhs );\n",protoname.Data(),protoname.Data()); defMod = kTRUE; };
02311 const char *ename = element->GetName();
02312 const char *colon2 = strstr(ename,"::");
02313 if (colon2) ename = colon2+2;
02314 if(element->GetArrayLength() <= 1) {
02315 fprintf(file," modrhs.%s = 0;\n",ename);
02316 } else {
02317 fprintf(file," memset(modrhs.%s,0,%d);\n",ename,element->GetSize());
02318 }
02319 } else {
02320 const char *ename = element->GetName();
02321 if (element->GetType() == kCharStar) {
02322 if (!defMod) {
02323 fprintf(file," %s &modrhs = const_cast<%s &>( rhs );\n",protoname.Data(),protoname.Data()); defMod = kTRUE;
02324 };
02325 fprintf(file," modrhs.%s = 0;\n",ename);
02326 } else if (TVirtualStreamerInfo::kOffsetP <= element->GetType() && element->GetType() < TVirtualStreamerInfo::kObject ) {
02327 if (!defMod) {
02328 fprintf(file," %s &modrhs = const_cast<%s &>( rhs );\n",protoname.Data(),protoname.Data()); defMod = kTRUE;
02329 };
02330 fprintf(file," modrhs.%s = 0;\n",ename);
02331 } else if (element->GetArrayLength() > 1) {
02332
02333 if (element->GetArrayDim() == 1) {
02334 fprintf(file," for (Int_t i=0;i<%d;i++) %s[i] = rhs.%s[i];\n",element->GetArrayLength(),ename,ename);
02335 } else if (element->GetArrayDim() >= 2) {
02336 fprintf(file," for (Int_t i=0;i<%d;i++) (&(%s",element->GetArrayLength(),ename);
02337 for (Int_t d = 0; d < element->GetArrayDim(); ++d) {
02338 fprintf(file,"[0]");
02339 }
02340 fprintf(file,"))[i] = (&(rhs.%s",ename);
02341 for (Int_t d = 0; d < element->GetArrayDim(); ++d) {
02342 fprintf(file,"[0]");
02343 }
02344 fprintf(file,"))[i];\n");
02345 }
02346 } else if (element->GetType() == TVirtualStreamerInfo::kSTLp) {
02347 if (!defMod) { fprintf(file," %s &modrhs = const_cast<%s &>( rhs );\n",protoname.Data(),protoname.Data()); defMod = kTRUE; };
02348 fprintf(file," modrhs.%s = 0;\n",ename);
02349 } else if (element->GetType() == TVirtualStreamerInfo::kSTL) {
02350 if (!defMod) {
02351 fprintf(file," %s &modrhs = const_cast<%s &>( rhs );\n",protoname.Data(),protoname.Data()); defMod = kTRUE;
02352 }
02353 if (element->IsBase()) {
02354 fprintf(file," modrhs.clear();\n");
02355 } else {
02356 fprintf(file," modrhs.%s.clear();\n",ename);
02357 }
02358 }
02359 }
02360 }
02361 }
02362
02363
02364 static void R__WriteDestructorBody(FILE *file, TIter &next)
02365 {
02366 TStreamerElement *element = 0;
02367 next.Reset();
02368 while ((element = (TStreamerElement*)next())) {
02369 if (element->GetType() == TVirtualStreamerInfo::kObjectp || element->GetType() == TVirtualStreamerInfo::kObjectP||
02370 element->GetType() == TVirtualStreamerInfo::kAnyp || element->GetType() == TVirtualStreamerInfo::kAnyP
02371 || element->GetType() == TVirtualStreamerInfo::kAnyPnoVT)
02372 {
02373 const char *ename = element->GetName();
02374 const char *colon2 = strstr(ename,"::");
02375 if (colon2) ename = colon2+2;
02376 if (element->TestBit(TStreamerElement::kDoNotDelete)) {
02377 if(element->GetArrayLength() <= 1) {
02378 fprintf(file," %s = 0;\n",ename);
02379 } else {
02380 fprintf(file," memset(%s,0,%d);\n",ename,element->GetSize());
02381 }
02382 } else {
02383 if(element->GetArrayLength() <= 1) {
02384 fprintf(file," delete %s; %s = 0;\n",ename,ename);
02385 } else {
02386 fprintf(file," for (Int_t i=0;i<%d;i++) delete %s[i]; memset(%s,0,%d);\n",element->GetArrayLength(),ename,ename,element->GetSize());
02387 }
02388 }
02389 }
02390 if (element->GetType() == TVirtualStreamerInfo::kCharStar) {
02391 const char *ename = element->GetName();
02392 if (element->TestBit(TStreamerElement::kDoNotDelete)) {
02393 fprintf(file," %s = 0;\n",ename);
02394 } else {
02395 fprintf(file," delete [] %s; %s = 0;\n",ename,ename);
02396 }
02397 }
02398 if (TVirtualStreamerInfo::kOffsetP <= element->GetType() && element->GetType() < TVirtualStreamerInfo::kObject ) {
02399 const char *ename = element->GetName();
02400 if (element->TestBit(TStreamerElement::kDoNotDelete)) {
02401 fprintf(file," %s = 0;\n",ename);
02402 } else if (element->HasCounter()) {
02403 fprintf(file," delete %s; %s = 0;\n",ename,ename);
02404 } else {
02405 fprintf(file," delete [] %s; %s = 0;\n",ename,ename);
02406 }
02407 }
02408 if (element->GetType() == TVirtualStreamerInfo::kSTL || element->GetType() == TVirtualStreamerInfo::kSTLp) {
02409 const char *ename = element->GetName();
02410 const char *prefix = "";
02411 if ( element->GetType() == TVirtualStreamerInfo::kSTLp ) {
02412 prefix = "*";
02413 } else if ( element->IsBase() ) {
02414 ename = "this";
02415 }
02416 TVirtualCollectionProxy *proxy = element->GetClassPointer()->GetCollectionProxy();
02417 if (!element->TestBit(TStreamerElement::kDoNotDelete) && element->GetClassPointer() && proxy) {
02418 Int_t stltype = ((TStreamerSTL*)element)->GetSTLtype();
02419
02420 if (proxy->HasPointers()) {
02421 fprintf(file," std::for_each( (%s %s).rbegin(), (%s %s).rend(), DeleteObjectFunctor() );\n",prefix,ename,prefix,ename);
02422
02423
02424
02425
02426 } else {
02427 if (stltype == TStreamerElement::kSTLmap || stltype == TStreamerElement::kSTLmultimap) {
02428 TString enamebasic = TMakeProject::UpdateAssociativeToVector(element->GetTypeNameBasic());
02429 std::vector<std::string> inside;
02430 int nestedLoc;
02431 TClassEdit::GetSplit(enamebasic, inside, nestedLoc, TClassEdit::kLong64);
02432 if (inside[1][inside[1].size()-1]=='*' || inside[2][inside[2].size()-1]=='*') {
02433 fprintf(file," std::for_each( (%s %s).rbegin(), (%s %s).rend(), DeleteObjectFunctor() );\n",prefix,ename,prefix,ename);
02434 }
02435 }
02436 }
02437 }
02438 if ( prefix[0] ) {
02439 fprintf(file," delete %s; %s = 0;\n",ename,ename);
02440 }
02441 }
02442 }
02443 }
02444
02445
02446 void TStreamerInfo::GenerateDeclaration(FILE *fp, FILE *sfp, const TList *subClasses, Bool_t top)
02447 {
02448
02449
02450 if (fClassVersion == -3) {
02451 return;
02452 }
02453
02454 bool needGenericTemplate = fElements==0 || fElements->GetEntries() == 0;
02455 Bool_t isTemplate = kFALSE;
02456 const char *clname = GetName();
02457 TString template_protoname;
02458 if (strchr(clname, ':')) {
02459
02460 Int_t len = strlen(clname);
02461 const char *name = clname;
02462 UInt_t nest = 0;
02463 UInt_t pr_pos = 0;
02464 for (Int_t cur = 0; cur < len; ++cur) {
02465 switch (clname[cur]) {
02466 case '<':
02467 ++nest;
02468 pr_pos = cur;
02469 isTemplate = kTRUE;
02470 break;
02471 case '>':
02472 --nest;
02473 break;
02474 case ':': {
02475 if (nest == 0 && clname[cur+1] == ':') {
02476
02477 isTemplate = kFALSE;
02478 name = clname + cur + 2;
02479 }
02480 break;
02481 }
02482 }
02483 }
02484 if (isTemplate) {
02485 template_protoname.Append(clname,pr_pos);
02486 }
02487 clname = name;
02488 } else {
02489 const char *where = strstr(clname, "<");
02490 isTemplate = where != 0;
02491 if (isTemplate) {
02492 template_protoname.Append(clname,where-clname);
02493 }
02494 }
02495
02496 if (needGenericTemplate && isTemplate) {
02497 TString templateName(TMakeProject::GetHeaderName("template "+template_protoname,0));
02498 fprintf(fp, "#ifndef %s_h\n", templateName.Data());
02499 fprintf(fp, "#define %s_h\n", templateName.Data());
02500 }
02501
02502 TString protoname;
02503 UInt_t numberOfNamespaces = TMakeProject::GenerateClassPrefix(fp, GetName(), top, protoname, 0, kFALSE, needGenericTemplate);
02504
02505
02506 TStreamerElement *element;
02507 TIter next(fElements);
02508 Int_t nbase = 0;
02509 while ((element = (TStreamerElement*)next())) {
02510 if (!element->IsBase()) continue;
02511 nbase++;
02512 const char *ename = element->GetName();
02513 if (nbase == 1) fprintf(fp," : public %s",ename);
02514 else fprintf(fp," , public %s",ename);
02515 }
02516 fprintf(fp," {\n");
02517
02518
02519 if (subClasses && subClasses->GetEntries()) {
02520 bool needheader = true;
02521
02522 TIter subnext(subClasses);
02523 TStreamerInfo *subinfo;
02524 Int_t len = strlen(GetName());
02525 while ((subinfo = (TStreamerInfo*)subnext())) {
02526 if (strncmp(GetName(),subinfo->GetName(),len)==0 && (subinfo->GetName()[len]==':') ) {
02527 if (subinfo->GetName()[len+1]==':' && strstr(subinfo->GetName()+len+2,":")==0) {
02528 if (needheader) {
02529 fprintf(fp,"\npublic:\n");
02530 fprintf(fp,"// Nested classes forward declaration.\n");
02531 needheader = false;
02532 }
02533 TString sub_protoname;
02534 UInt_t sub_numberOfClasses = 0;
02535 UInt_t sub_numberOfNamespaces;
02536 if (subinfo->GetClassVersion() == -3) {
02537 sub_numberOfNamespaces = TMakeProject::GenerateClassPrefix(fp, subinfo->GetName() + len+2, kFALSE, sub_protoname, &sub_numberOfClasses, 3);
02538 } else {
02539 sub_numberOfNamespaces = TMakeProject::GenerateClassPrefix(fp, subinfo->GetName() + len+2, kFALSE, sub_protoname, &sub_numberOfClasses, kFALSE);
02540 fprintf(fp, ";\n");
02541 }
02542
02543 for (UInt_t i = 0;i < sub_numberOfClasses;++i) {
02544 fprintf(fp, "}; // end of class.\n");
02545 }
02546 if (sub_numberOfNamespaces > 0) {
02547 Error("GenerateDeclaration","Nested classes %s thought to be inside a namespace inside the class %s",subinfo->GetName(),GetName());
02548 }
02549 }
02550 }
02551 }
02552 }
02553
02554 fprintf(fp,"\npublic:\n");
02555 fprintf(fp,"// Nested classes declaration.\n");
02556
02557
02558 if (subClasses && subClasses->GetEntries()) {
02559 TIter subnext(subClasses,kIterBackward);
02560 TStreamerInfo *subinfo;
02561 Int_t len = strlen(GetName());
02562 while ((subinfo = (TStreamerInfo*)subnext())) {
02563 if (strncmp(GetName(),subinfo->GetName(),len)==0 && (subinfo->GetName()[len]==':')) {
02564 if (subinfo->GetName()[len+1]==':' && strstr(subinfo->GetName()+len+2,":")==0) {
02565 subinfo->GenerateDeclaration(fp, sfp, subClasses, kFALSE);
02566 }
02567 }
02568 }
02569 }
02570
02571 fprintf(fp,"\npublic:\n");
02572 fprintf(fp,"// Data Members.\n");
02573
02574 {
02575
02576 TString name(128);
02577 Int_t ltype = 12;
02578 Int_t ldata = 10;
02579 Int_t lt,ld,is;
02580 TString line;
02581 line.Resize(kMaxLen);
02582 next.Reset();
02583 while ((element = (TStreamerElement*)next())) {
02584
02585 if (element->IsBase()) continue;
02586 const char *ename = element->GetName();
02587
02588 name = ename;
02589 for (Int_t i=0;i < element->GetArrayDim();i++) {
02590 name += TString::Format("[%d]",element->GetMaxIndex(i));
02591 }
02592 name += ";";
02593 ld = name.Length();
02594
02595 TString enamebasic = element->GetTypeNameBasic();
02596 if (element->IsA() == TStreamerSTL::Class()) {
02597
02598
02599
02600
02601 Int_t stltype = ((TStreamerSTL*)element)->GetSTLtype();
02602 switch (stltype) {
02603 case TStreamerElement::kSTLmap:
02604 case TStreamerElement::kSTLmultimap:
02605 case TStreamerElement::kSTLset:
02606 case TStreamerElement::kSTLmultiset:
02607 {
02608 enamebasic = TMakeProject::UpdateAssociativeToVector(enamebasic);
02609 }
02610 default:
02611
02612 break;
02613 }
02614 }
02615
02616 lt = enamebasic.Length();
02617
02618 line = " ";
02619 line += enamebasic;
02620 if (lt>=ltype) ltype = lt+1;
02621
02622 for (is = 3+lt; is < (3+ltype); ++is) line += ' ';
02623
02624 line += name;
02625 if (element->IsaPointer() && !strchr(line,'*')) line[2+ltype] = '*';
02626
02627 if (ld>=ldata) ldata = ld+1;
02628 for (is = 3+ltype+ld; is < (3+ltype+ldata); ++is) line += ' ';
02629
02630 line += " //";
02631 line += element->GetTitle();
02632 fprintf(fp,"%s\n",line.Data());
02633 }
02634 }
02635 if (needGenericTemplate && isTemplate) {
02636
02637 fprintf(fp,"\n %s() {\n",protoname.Data());
02638 R__WriteConstructorBody(fp,next);
02639 fprintf(fp," }\n");
02640 fprintf(fp," %s(const %s & rhs )\n",protoname.Data(),protoname.Data());
02641 R__WriteMoveConstructorBody(fp,protoname,next);
02642 fprintf(fp," }\n");
02643 fprintf(fp," virtual ~%s() {\n",protoname.Data());
02644 R__WriteDestructorBody(fp,next);
02645 fprintf(fp," }\n\n");
02646
02647 } else {
02648
02649 fprintf(fp,"\n %s();\n",protoname.Data());
02650 fprintf(fp," %s(const %s & );\n",protoname.Data(),protoname.Data());
02651 fprintf(fp," virtual ~%s();\n\n",protoname.Data());
02652
02653
02654 TString guard( TMakeProject::GetHeaderName( GetName(), 0, kTRUE ) );
02655 fprintf(sfp,"#ifndef %s_cxx\n",guard.Data());
02656 fprintf(sfp,"#define %s_cxx\n",guard.Data());
02657 fprintf(sfp,"%s::%s() {\n",GetName(),protoname.Data());
02658 R__WriteConstructorBody(sfp,next);
02659 fprintf(sfp,"}\n");
02660
02661 fprintf(sfp,"%s::%s(const %s & rhs)\n",GetName(),protoname.Data(),protoname.Data());
02662 R__WriteMoveConstructorBody(sfp,protoname,next);
02663 fprintf(sfp,"}\n");
02664
02665 fprintf(sfp,"%s::~%s() {\n",GetName(),protoname.Data());
02666 R__WriteDestructorBody(sfp,next);
02667 fprintf(sfp,"}\n");
02668 fprintf(sfp,"#endif // %s_cxx\n\n",guard.Data());
02669 }
02670
02671 TClass *cl = gROOT->GetClass(GetName());
02672 if (fClassVersion > 1 || (cl && cl->InheritsFrom(TObject::Class())) ) {
02673
02674 fprintf(fp," ClassDef(%s,%d); // Generated by MakeProject.\n",protoname.Data(),fClassVersion + 1);
02675 }
02676 fprintf(fp,"};\n");
02677
02678 for(UInt_t i=0;i<numberOfNamespaces;++i) {
02679 fprintf(fp,"} // namespace\n");
02680 }
02681
02682 if (needGenericTemplate && isTemplate) {
02683 fprintf(fp,"#endif // generic template declaration\n");
02684 }
02685 }
02686
02687
02688 UInt_t TStreamerInfo::GenerateIncludes(FILE *fp, char *inclist, const TList *extrainfos)
02689 {
02690
02691
02692 UInt_t ninc = 0;
02693
02694 const char *clname = GetName();
02695 if (strchr(clname,'<')) {
02696
02697 ninc += TMakeProject::GenerateIncludeForTemplate(fp, clname, inclist, kFALSE, extrainfos);
02698 }
02699
02700 TString name(1024);
02701 Int_t ltype = 10;
02702 Int_t ldata = 10;
02703 Int_t lt;
02704 Int_t ld;
02705 TIter next(fElements);
02706 TStreamerElement *element;
02707 Bool_t incRiostream = kFALSE;
02708 while ((element = (TStreamerElement*)next())) {
02709
02710 const char *ename = element->GetName();
02711 const char *colon2 = strstr(ename,"::");
02712 if (colon2) ename = colon2+2;
02713 name = ename;
02714 for (Int_t i=0;i < element->GetArrayDim();i++) {
02715 name += TString::Format("[%d]",element->GetMaxIndex(i));
02716 }
02717 ld = name.Length();
02718 lt = strlen(element->GetTypeName());
02719 if (ltype < lt) ltype = lt;
02720 if (ldata < ld) ldata = ld;
02721
02722
02723 if (!incRiostream && element->InheritsFrom(TStreamerSTL::Class())) {
02724 incRiostream = kTRUE;
02725 TMakeProject::AddInclude( fp, "Riostream.h", kFALSE, inclist);
02726 }
02727
02728
02729 const char *include = element->GetInclude();
02730 if (strlen(include) == 0) continue;
02731
02732 Bool_t greater = (include[0]=='<');
02733 include++;
02734
02735 if (strncmp(include,"include/",8)==0) {
02736 include += 8;
02737 }
02738 if (strncmp(include,"include\\",9)==0) {
02739 include += 9;
02740 }
02741 if (strncmp(element->GetTypeName(),"pair<",strlen("pair<"))==0) {
02742 TMakeProject::AddInclude( fp, "utility", kTRUE, inclist);
02743 } else if (strncmp(element->GetTypeName(),"auto_ptr<",strlen("auto_ptr<"))==0) {
02744 TMakeProject::AddInclude( fp, "memory", kTRUE, inclist);
02745 } else {
02746 TString incName( include, strlen(include)-1 );
02747 incName = TMakeProject::GetHeaderName(incName,extrainfos);
02748 TMakeProject::AddInclude( fp, incName.Data(), greater, inclist);
02749 }
02750
02751 if (strchr(element->GetTypeName(),'<')) {
02752
02753 ninc += TMakeProject::GenerateIncludeForTemplate(fp, element->GetTypeName(), inclist, kFALSE, extrainfos);
02754 }
02755 }
02756 if (inclist[0]==0) {
02757 TMakeProject::AddInclude( fp, "TNamed.h", kFALSE, inclist);
02758 }
02759 return ninc;
02760 }
02761
02762
02763 Int_t TStreamerInfo::GenerateHeaderFile(const char *dirname, const TList *subClasses, const TList *extrainfos)
02764 {
02765
02766
02767
02768
02769 if (TClassEdit::IsSTLCont(GetName())) return 0;
02770 if (strncmp(GetName(),"pair<",strlen("pair<"))==0) return 0;
02771 if (strncmp(GetName(),"auto_ptr<",strlen("auto_ptr<"))==0) return 0;
02772
02773 TClass *cl = TClass::GetClass(GetName());
02774 if (cl) {
02775 if (cl->GetClassInfo()) return 0;
02776 }
02777 Bool_t isTemplate = kFALSE;
02778 if (strchr(GetName(),':')) {
02779 UInt_t len = strlen(GetName());
02780 UInt_t nest = 0;
02781 UInt_t scope = 0;
02782 for(UInt_t i=len; i>0; --i) {
02783 switch(GetName()[i]) {
02784 case '>': ++nest; if (scope==0) { isTemplate = kTRUE; } break;
02785 case '<': --nest; break;
02786 case ':':
02787 if (nest==0 && GetName()[i-1]==':') {
02788
02789 TString nsname(GetName(), i-1);
02790 cl = gROOT->GetClass(nsname);
02791 if (cl && (cl->Size()!=0 || (cl->Size()==0 && cl->GetClassInfo()==0 ))) {
02792
02793 return 0;
02794 } else if (cl == 0 && extrainfos != 0) {
02795 TStreamerInfo *clinfo = (TStreamerInfo*)extrainfos->FindObject(nsname);
02796 if (clinfo && clinfo->GetClassVersion() == -5) {
02797
02798 return 0;
02799 }
02800 }
02801 ++scope;
02802 }
02803 break;
02804 }
02805 }
02806 }
02807 Bool_t needGenericTemplate = isTemplate && (fElements==0 || fElements->GetEntries()==0);
02808
02809 if (gDebug) printf("generating code for class %s\n",GetName());
02810
02811
02812
02813 TString headername( TMakeProject::GetHeaderName( GetName(), extrainfos ) );
02814 TString filename;
02815 filename.Form("%s/%s.h",dirname,headername.Data());
02816
02817 FILE *fp = fopen(filename.Data(),"w");
02818 if (!fp) {
02819 Error("MakeProject","Cannot open output file:%s\n",filename.Data());
02820 return 0;
02821 }
02822
02823 filename.Form("%s/%sProjectHeaders.h",dirname,dirname);
02824 FILE *allfp = fopen(filename.Data(),"a");
02825 if (!allfp) {
02826 Error("MakeProject","Cannot open output file:%s\n",filename.Data());
02827 fclose(fp);
02828 return 0;
02829 }
02830 fprintf(allfp,"#include \"%s.h\"\n", headername.Data());
02831 fclose(allfp);
02832
02833 char *inclist = new char[50000];
02834 inclist[0] = 0;
02835
02836
02837 TDatime td;
02838 fprintf(fp,"//////////////////////////////////////////////////////////\n");
02839 fprintf(fp,"// This class has been generated by TFile::MakeProject\n");
02840 fprintf(fp,"// (%s by ROOT version %s)\n",td.AsString(),gROOT->GetVersion());
02841 fprintf(fp,"// from the StreamerInfo in file %s\n",gDirectory->GetFile()->GetName());
02842 fprintf(fp,"//////////////////////////////////////////////////////////\n");
02843 fprintf(fp,"\n");
02844 fprintf(fp,"\n");
02845 fprintf(fp,"#ifndef %s_h\n",headername.Data());
02846 fprintf(fp,"#define %s_h\n",headername.Data());
02847 TMakeProject::GenerateForwardDeclaration(fp, GetName(), inclist, kFALSE, needGenericTemplate, extrainfos);
02848 fprintf(fp,"\n");
02849
02850 UInt_t ninc = 0;
02851 ninc += GenerateIncludes(fp, inclist, extrainfos);
02852 if (subClasses) {
02853 TIter subnext(subClasses);
02854 TStreamerInfo *subinfo;
02855 while ((subinfo = (TStreamerInfo*)subnext())) {
02856 ninc = subinfo->GenerateIncludes(fp, inclist, extrainfos);
02857 }
02858 }
02859 fprintf(fp,"\n");
02860
02861 TString sourcename; sourcename.Form( "%s/%sProjectSource.cxx", dirname, dirname );
02862 FILE *sfp = fopen( sourcename.Data(), "a" );
02863 GenerateDeclaration(fp, sfp, subClasses);
02864
02865 TMakeProject::GeneratePostDeclaration(fp, this, inclist);
02866
02867 fprintf(fp,"#endif\n");
02868
02869 delete [] inclist;
02870 fclose(fp);
02871 fclose(sfp);
02872 return 1;
02873 }
02874
02875
02876 TStreamerElement *TStreamerInfo::GetCurrentElement()
02877 {
02878
02879
02880 return fgElement;
02881 }
02882
02883
02884 Int_t TStreamerInfo::GetDataMemberOffset(TDataMember *dm, TMemberStreamer *&streamer) const
02885 {
02886
02887
02888
02889 TIter nextr(fClass->GetListOfRealData());
02890 char dmbracket[256];
02891 snprintf(dmbracket,255,"%s[",dm->GetName());
02892 Int_t offset = kMissing;
02893 if (fClass->GetDeclFileLine() < 0) offset = dm->GetOffset();
02894 TRealData *rdm;
02895 while ((rdm = (TRealData*)nextr())) {
02896 char *rdmc = (char*)rdm->GetName();
02897
02898
02899 if (dm->IsaPointer() && rdmc[0] == '*') rdmc++;
02900
02901 if (rdm->GetDataMember() != dm) continue;
02902 if (strcmp(rdmc,dm->GetName()) == 0) {
02903 offset = rdm->GetThisOffset();
02904 streamer = rdm->GetStreamer();
02905 break;
02906 }
02907 if (strcmp(rdm->GetName(),dm->GetName()) == 0) {
02908 if (rdm->IsObject()) {
02909 offset = rdm->GetThisOffset();
02910 streamer = rdm->GetStreamer();
02911 break;
02912 }
02913 }
02914 if (strstr(rdm->GetName(),dmbracket)) {
02915 offset = rdm->GetThisOffset();
02916 streamer = rdm->GetStreamer();
02917 break;
02918 }
02919 }
02920 return offset;
02921 }
02922
02923
02924 Int_t TStreamerInfo::GetOffset(const char *elementName) const
02925 {
02926
02927
02928 if (elementName == 0) return 0;
02929
02930 Int_t offset = 0;
02931 TStreamerElement *elem = (TStreamerElement*)fElements->FindObject(elementName);
02932 if (elem) offset = elem->GetOffset();
02933
02934 return offset;
02935 }
02936
02937
02938 Int_t TStreamerInfo::GetSize() const
02939 {
02940
02941
02942 return fSize;
02943 }
02944
02945
02946 Int_t TStreamerInfo::GetSizeElements() const
02947 {
02948
02949
02950
02951 TIter next(fElements);
02952 TStreamerElement *element;
02953 Int_t asize = 0;
02954 while ((element = (TStreamerElement*)next())) {
02955 asize += element->GetSize();
02956 }
02957 return asize;
02958 }
02959
02960
02961 TStreamerElement* TStreamerInfo::GetStreamerElement(const char* datamember, Int_t& offset) const
02962 {
02963
02964
02965
02966
02967
02968
02969 if (!fElements) {
02970 return 0;
02971 }
02972
02973
02974
02975 TStreamerElement* element = (TStreamerElement*) fElements->FindObject(datamember);
02976 if (element) {
02977 offset = element->GetOffset();
02978 return element;
02979 }
02980
02981
02982
02983 if (fClass->GetClassInfo()) {
02984
02985 TStreamerElement* base_element = 0;
02986 TBaseClass* base = 0;
02987 TClass* base_cl = 0;
02988 Int_t base_offset = 0;
02989 Int_t local_offset = 0;
02990 TIter nextb(fClass->GetListOfBases());
02991
02992 while ((base = (TBaseClass*) nextb())) {
02993 base_cl = TClass::GetClass(base->GetName());
02994 base_element = (TStreamerElement*) fElements->FindObject(base->GetName());
02995 if (!base_cl || !base_element) {
02996 continue;
02997 }
02998 base_offset = base_element->GetOffset();
02999 element = ((TStreamerInfo*)base_cl->GetStreamerInfo())->GetStreamerElement(datamember, local_offset);
03000 if (element) {
03001 offset = base_offset + local_offset;
03002 return element;
03003 }
03004 }
03005 } else {
03006
03007 TIter next(fElements);
03008 TStreamerElement* curelem = 0;
03009 while ((curelem = (TStreamerElement*) next())) {
03010 if (curelem->InheritsFrom(TStreamerBase::Class())) {
03011 TClass* baseClass = curelem->GetClassPointer();
03012 if (!baseClass) {
03013 continue;
03014 }
03015 Int_t base_offset = curelem->GetOffset();
03016 Int_t local_offset = 0;
03017 element = ((TStreamerInfo*)baseClass->GetStreamerInfo())->GetStreamerElement(datamember, local_offset);
03018 if (element) {
03019 offset = base_offset + local_offset;
03020 return element;
03021 }
03022 }
03023 }
03024 }
03025 return 0;
03026 }
03027
03028
03029 TStreamerElement* TStreamerInfo::GetStreamerElementReal(Int_t i, Int_t j) const
03030 {
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062 if (i < 0 || i >= fNdata) return 0;
03063 if (j < 0) return 0;
03064 if (!fElements) return 0;
03065 TStreamerElement *se = (TStreamerElement*)fElem[i];
03066 if (!se) return 0;
03067 Int_t nelems = fElements->GetEntriesFast();
03068 for (Int_t ise=0;ise < nelems;ise++) {
03069 if (se != (TStreamerElement*)fElements->UncheckedAt(ise)) continue;
03070 if (ise+j >= nelems) return 0;
03071 return (TStreamerElement*)fElements->UncheckedAt(ise+j);
03072 }
03073 return 0;
03074 }
03075
03076
03077 Double_t TStreamerInfo::GetValueAux(Int_t type, void *ladd, Int_t k, Int_t len)
03078 {
03079
03080
03081 if (type>=kConv && type<kSTL) {
03082 type -= kConv;
03083 }
03084 switch (type) {
03085
03086 case kBool: {Bool_t *val = (Bool_t*)ladd; return Double_t(*val);}
03087 case kChar: {Char_t *val = (Char_t*)ladd; return Double_t(*val);}
03088 case kShort: {Short_t *val = (Short_t*)ladd; return Double_t(*val);}
03089 case kInt: {Int_t *val = (Int_t*)ladd; return Double_t(*val);}
03090 case kLong: {Long_t *val = (Long_t*)ladd; return Double_t(*val);}
03091 case kLong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(*val);}
03092 case kFloat: {Float_t *val = (Float_t*)ladd; return Double_t(*val);}
03093 case kFloat16: {Float_t *val = (Float_t*)ladd; return Double_t(*val);}
03094 case kDouble: {Double_t *val = (Double_t*)ladd; return Double_t(*val);}
03095 case kDouble32: {Double_t *val = (Double_t*)ladd; return Double_t(*val);}
03096 case kUChar: {UChar_t *val = (UChar_t*)ladd; return Double_t(*val);}
03097 case kUShort: {UShort_t *val = (UShort_t*)ladd; return Double_t(*val);}
03098 case kUInt: {UInt_t *val = (UInt_t*)ladd; return Double_t(*val);}
03099 case kULong: {ULong_t *val = (ULong_t*)ladd; return Double_t(*val);}
03100 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
03101 case kULong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(*val);}
03102 #else
03103 case kULong64: {ULong64_t *val= (ULong64_t*)ladd; return Double_t(*val);}
03104 #endif
03105 case kBits: {UInt_t *val = (UInt_t*)ladd; return Double_t(*val);}
03106
03107
03108 case kOffsetL + kBool: {Bool_t *val = (Bool_t*)ladd; return Double_t(val[k]);}
03109 case kOffsetL + kChar: {Char_t *val = (Char_t*)ladd; return Double_t(val[k]);}
03110 case kOffsetL + kShort: {Short_t *val = (Short_t*)ladd; return Double_t(val[k]);}
03111 case kOffsetL + kInt: {Int_t *val = (Int_t*)ladd; return Double_t(val[k]);}
03112 case kOffsetL + kLong: {Long_t *val = (Long_t*)ladd; return Double_t(val[k]);}
03113 case kOffsetL + kLong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(val[k]);}
03114 case kOffsetL + kFloat: {Float_t *val = (Float_t*)ladd; return Double_t(val[k]);}
03115 case kOffsetL + kFloat16: {Float_t *val = (Float_t*)ladd; return Double_t(val[k]);}
03116 case kOffsetL + kDouble: {Double_t *val = (Double_t*)ladd; return Double_t(val[k]);}
03117 case kOffsetL + kDouble32:{Double_t *val = (Double_t*)ladd; return Double_t(val[k]);}
03118 case kOffsetL + kUChar: {UChar_t *val = (UChar_t*)ladd; return Double_t(val[k]);}
03119 case kOffsetL + kUShort: {UShort_t *val = (UShort_t*)ladd; return Double_t(val[k]);}
03120 case kOffsetL + kUInt: {UInt_t *val = (UInt_t*)ladd; return Double_t(val[k]);}
03121 case kOffsetL + kULong: {ULong_t *val = (ULong_t*)ladd; return Double_t(val[k]);}
03122 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
03123 case kOffsetL + kULong64: {Long64_t *val = (Long64_t*)ladd; return Double_t(val[k]);}
03124 #else
03125 case kOffsetL + kULong64:{ULong64_t *val= (ULong64_t*)ladd; return Double_t(val[k]);}
03126 #endif
03127
03128 #define READ_ARRAY(TYPE_t) \
03129 { \
03130 Int_t sub_instance, index; \
03131 Int_t instance = k; \
03132 if (len) { \
03133 index = instance / len; \
03134 sub_instance = instance % len; \
03135 } else { \
03136 index = instance; \
03137 sub_instance = 0; \
03138 } \
03139 TYPE_t **val =(TYPE_t**)(ladd); \
03140 return Double_t((val[sub_instance])[index]); \
03141 }
03142
03143
03144 case kOffsetP + kBool_t: READ_ARRAY(Bool_t)
03145 case kOffsetP + kChar_t: READ_ARRAY(Char_t)
03146 case kOffsetP + kShort_t: READ_ARRAY(Short_t)
03147 case kOffsetP + kInt_t: READ_ARRAY(Int_t)
03148 case kOffsetP + kLong_t: READ_ARRAY(Long_t)
03149 case kOffsetP + kLong64_t: READ_ARRAY(Long64_t)
03150 case kOffsetP + kFloat16_t:
03151 case kOffsetP + kFloat_t: READ_ARRAY(Float_t)
03152 case kOffsetP + kDouble32_t:
03153 case kOffsetP + kDouble_t: READ_ARRAY(Double_t)
03154 case kOffsetP + kUChar_t: READ_ARRAY(UChar_t)
03155 case kOffsetP + kUShort_t: READ_ARRAY(UShort_t)
03156 case kOffsetP + kUInt_t: READ_ARRAY(UInt_t)
03157 case kOffsetP + kULong_t: READ_ARRAY(ULong_t)
03158 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
03159 case kOffsetP + kULong64_t: READ_ARRAY(Long64_t)
03160 #else
03161 case kOffsetP + kULong64_t: READ_ARRAY(ULong64_t)
03162 #endif
03163
03164
03165 case kCounter: {Int_t *val = (Int_t*)ladd; return Double_t(*val);}
03166 }
03167 return 0;
03168 }
03169
03170
03171 Double_t TStreamerInfo::GetValue(char *pointer, Int_t i, Int_t j, Int_t len) const
03172 {
03173
03174
03175
03176
03177
03178
03179
03180
03181 char *ladd;
03182 Int_t atype;
03183 if (len >= 0) {
03184 ladd = pointer;
03185 atype = i;
03186 } else {
03187 if (i < 0) return 0;
03188 ladd = pointer + fOffset[i];
03189 atype = fNewType[i];
03190 len = ((TStreamerElement*)fElem[i])->GetArrayLength();
03191 if (atype == kSTL) {
03192 TClass *newClass = ((TStreamerElement*)fElem[i])->GetNewClass();
03193 if (newClass == 0) {
03194 newClass = ((TStreamerElement*)fElem[i])->GetClassPointer();
03195 }
03196 TClass *innerClass = newClass->GetCollectionProxy()->GetValueClass();
03197 if (innerClass) {
03198 return 0;
03199 } else {
03200 TVirtualCollectionProxy *proxy = newClass->GetCollectionProxy();
03201 atype = proxy->GetType();
03202 TVirtualCollectionProxy::TPushPop pop(proxy,ladd);
03203 Int_t nc = proxy->Size();
03204 if (j >= nc) return 0;
03205 char *element_ptr = (char*)proxy->At(j);
03206 return GetValueAux(atype,element_ptr,0,1);
03207 }
03208 }
03209 }
03210 return GetValueAux(atype,ladd,j,len);
03211 }
03212
03213
03214 Double_t TStreamerInfo::GetValueClones(TClonesArray *clones, Int_t i, Int_t j, int k, Int_t eoffset) const
03215 {
03216
03217
03218
03219 Int_t nc = clones->GetEntriesFast();
03220 if (j >= nc) return 0;
03221
03222 char *pointer = (char*)clones->UncheckedAt(j);
03223 char *ladd = pointer + eoffset + fOffset[i];
03224 return GetValueAux(fType[i],ladd,k,((TStreamerElement*)fElem[i])->GetArrayLength());
03225 }
03226
03227
03228 Double_t TStreamerInfo::GetValueSTL(TVirtualCollectionProxy *cont, Int_t i, Int_t j, int k, Int_t eoffset) const
03229 {
03230
03231
03232
03233 Int_t nc = cont->Size();
03234 if (j >= nc) return 0;
03235
03236 char *pointer = (char*)cont->At(j);
03237 char *ladd = pointer + eoffset + fOffset[i];
03238 return GetValueAux(fType[i],ladd,k,((TStreamerElement*)fElem[i])->GetArrayLength());
03239 }
03240
03241
03242 Double_t TStreamerInfo::GetValueSTLP(TVirtualCollectionProxy *cont, Int_t i, Int_t j, int k, Int_t eoffset) const
03243 {
03244
03245
03246 Int_t nc = cont->Size();
03247
03248 if (j >= nc) return 0;
03249
03250 char **ptr = (char**)cont->At(j);
03251 char *pointer = *ptr;
03252
03253 char *ladd = pointer + eoffset + fOffset[i];
03254 return GetValueAux(fType[i],ladd,k,((TStreamerElement*)fElem[i])->GetArrayLength());
03255 }
03256
03257
03258 void TStreamerInfo::InsertArtificialElements(const TObjArray *rules)
03259 {
03260
03261
03262 if (!rules) return;
03263
03264 TIter next(fElements);
03265 UInt_t count = 0;
03266
03267 for(Int_t art = 0; art < rules->GetEntries(); ++art) {
03268 ROOT::TSchemaRule *rule = (ROOT::TSchemaRule*)rules->At(art);
03269 if( rule->IsRenameRule() || rule->IsAliasRule() )
03270 continue;
03271 next.Reset();
03272 Bool_t match = kFALSE;
03273 TStreamerElement *element;
03274 while ((element = (TStreamerElement*) next())) {
03275 if ( rule->HasTarget( element->GetName() ) ) {
03276
03277
03278 match = ! ((ROOT::TSchemaMatch*)rules)->HasRuleWithSource( element->GetName(), kTRUE );
03279
03280
03281 if ( rule->GetAttributes()[0] != 0 ) {
03282 TString attr( rule->GetAttributes() );
03283 attr.ToLower();
03284 if (attr.Contains("owner")) {
03285 if (attr.Contains("notowner")) {
03286 element->SetBit(TStreamerElement::kDoNotDelete);
03287 } else {
03288 element->ResetBit(TStreamerElement::kDoNotDelete);
03289 }
03290 }
03291
03292 }
03293 break;
03294 }
03295 }
03296 if (!match) {
03297 TStreamerArtificial *newel;
03298 if (rule->GetTarget()==0) {
03299 TString newName;
03300 newName.Form("%s_rule%d",fClass->GetName(),count);
03301 newel = new TStreamerArtificial(newName,"",
03302 fClass->GetDataMemberOffset(newName),
03303 TStreamerInfo::kArtificial,
03304 "void");
03305 newel->SetReadFunc( rule->GetReadFunctionPointer() );
03306 newel->SetReadRawFunc( rule->GetReadRawFunctionPointer() );
03307 fElements->Add(newel);
03308 } else {
03309 TObjString * objstr = (TObjString*)(rule->GetTarget()->At(0));
03310 if (objstr) {
03311 TString newName = objstr->String();
03312 if ( fClass->GetDataMember( newName ) ) {
03313 newel = new TStreamerArtificial(newName,"",
03314 fClass->GetDataMemberOffset(newName),
03315 TStreamerInfo::kArtificial,
03316 fClass->GetDataMember( newName )->GetTypeName());
03317 newel->SetReadFunc( rule->GetReadFunctionPointer() );
03318 newel->SetReadRawFunc( rule->GetReadRawFunctionPointer() );
03319 fElements->Add(newel);
03320 } else {
03321
03322
03323 }
03324 for(Int_t other = 1; other < rule->GetTarget()->GetEntries(); ++other) {
03325 objstr = (TObjString*)(rule->GetTarget()->At(other));
03326 if (objstr) {
03327 newName = objstr->String();
03328 if ( fClass->GetDataMember( newName ) ) {
03329 newel = new TStreamerArtificial(newName,"",
03330 fClass->GetDataMemberOffset(newName),
03331 TStreamerInfo::kArtificial,
03332 fClass->GetDataMember( newName )->GetTypeName());
03333 fElements->Add(newel);
03334 }
03335 }
03336 }
03337 }
03338 }
03339 }
03340 }
03341 }
03342
03343
03344 void TStreamerInfo::ls(Option_t *option) const
03345 {
03346
03347 if (fClass && fClass->IsForeign() && fClass->GetClassVersion()<2) {
03348 Printf("\nStreamerInfo for class: %s, checksum=0x%x",GetName(),GetCheckSum());
03349 } else {
03350 Printf("\nStreamerInfo for class: %s, version=%d, checksum=0x%x",GetName(),fClassVersion,GetCheckSum());
03351 }
03352
03353 if (fElements) {
03354 TIter next(fElements);
03355 TObject *obj;
03356 while ((obj = next()))
03357 obj->ls(option);
03358 }
03359 for (Int_t i=0;i < fNdata;i++) {
03360 TStreamerElement *element = (TStreamerElement*)fElem[i];
03361 TString sequenceType = " [";
03362 Bool_t first = kTRUE;
03363 if (element->TestBit(TStreamerElement::kCache)) {
03364 first = kFALSE;
03365 sequenceType += "cached";
03366 }
03367 if (element->TestBit(TStreamerElement::kRepeat)) {
03368 if (!first) sequenceType += ",";
03369 first = kFALSE;
03370 sequenceType += "repeat";
03371 }
03372 if (element->TestBit(TStreamerElement::kDoNotDelete)) {
03373 if (!first) sequenceType += ",";
03374 first = kFALSE;
03375 sequenceType += "nodelete";
03376 }
03377 if (first) sequenceType.Clear();
03378 else sequenceType += "]";
03379
03380 Printf(" i=%2d, %-15s type=%3d, offset=%3d, len=%d, method=%ld%s",i,element->GetName(),fType[i],fOffset[i],fLength[i],fMethod[i],sequenceType.Data());
03381 }
03382 }
03383
03384
03385 void* TStreamerInfo::New(void *obj)
03386 {
03387
03388
03389
03390
03391
03392 char* p = (char*) obj;
03393
03394 TIter next(fElements);
03395
03396 if (!p) {
03397
03398 p = new char[fSize];
03399 memset(p, 0, fSize);
03400 }
03401
03402 next.Reset();
03403 TStreamerElement* element = (TStreamerElement*) next();
03404
03405 for (; element; element = (TStreamerElement*) next()) {
03406
03407
03408 if (element->GetOffset() == kMissing) {
03409 continue;
03410 }
03411
03412
03413
03414 TClass* cle = element->GetClassPointer();
03415 if (!cle) {
03416 continue;
03417 }
03418
03419 char* eaddr = p + element->GetOffset();
03420 Int_t etype = element->GetType();
03421
03422
03423
03424 switch (etype) {
03425
03426 case kAnyP:
03427 case kObjectP:
03428 case kSTLp:
03429 {
03430
03431 char** r = (char**) eaddr;
03432 Int_t len = element->GetArrayLength();
03433 for (Int_t i = 0; i < len; ++i) {
03434 r[i] = 0;
03435 }
03436 }
03437 break;
03438
03439 case kObjectp:
03440 case kAnyp:
03441 {
03442
03443
03444
03445 if (cle != TClonesArray::Class()) {
03446 void** r = (void**) eaddr;
03447 *r = cle->New();
03448 } else {
03449
03450
03451
03452
03453 const char* title = element->GetTitle();
03454 const char* bracket1 = strrchr(title, '(');
03455 const char* bracket2 = strrchr(title, ')');
03456 if (bracket1 && bracket2 && (bracket2 != (bracket1 + 1))) {
03457 Int_t len = bracket2 - (bracket1 + 1);
03458 char* clonesClass = new char[len+1];
03459 clonesClass[0] = '\0';
03460 strncat(clonesClass, bracket1 + 1, len);
03461 void** r = (void**) eaddr;
03462 *r = (void*) new TClonesArray(clonesClass);
03463 delete[] clonesClass;
03464 } else {
03465
03466 void** r = (void**) eaddr;
03467 *r = (void*) new TClonesArray();
03468 }
03469 }
03470 }
03471 break;
03472
03473 case kBase:
03474 case kObject:
03475 case kAny:
03476 case kTObject:
03477 case kTString:
03478 case kTNamed:
03479 case kSTL:
03480 {
03481 cle->New(eaddr);
03482 }
03483 break;
03484
03485 case kObject + kOffsetL:
03486 case kAny + kOffsetL:
03487 case kTObject + kOffsetL:
03488 case kTString + kOffsetL:
03489 case kTNamed + kOffsetL:
03490 case kSTL + kOffsetL:
03491 {
03492 Int_t size = cle->Size();
03493 char* r = eaddr;
03494 Int_t len = element->GetArrayLength();
03495 for (Int_t i = 0; i < len; ++i, r += size) {
03496 cle->New(r);
03497 }
03498 }
03499 break;
03500
03501 }
03502 }
03503
03504 for(int nbase = 0; nbase < fNVirtualInfoLoc; ++nbase) {
03505 *(TStreamerInfo**)(p + fVirtualInfoLoc[nbase]) = this;
03506 }
03507 ++fLiveCount;
03508 return p;
03509 }
03510
03511
03512 void* TStreamerInfo::NewArray(Long_t nElements, void *ary)
03513 {
03514
03515
03516
03517 if (fClass == 0) {
03518 Error("NewArray", "TClass pointer is null!");
03519 return 0;
03520 }
03521
03522 Int_t size = fClass->Size();
03523
03524 char* p = (char*) ary;
03525
03526 if (!p) {
03527 Long_t len = nElements * size + sizeof(Long_t)*2;
03528 p = new char[len];
03529 memset(p, 0, len);
03530 }
03531
03532
03533 Long_t* r = (Long_t*) p;
03534 r[0] = size;
03535 r[1] = nElements;
03536 char* dataBegin = (char*) &r[2];
03537
03538
03539 p = dataBegin;
03540 for (Long_t cnt = 0; cnt < nElements; ++cnt) {
03541 New(p);
03542 p += size;
03543 }
03544
03545 return dataBegin;
03546 }
03547
03548
03549 #define DeleteBasicPointer(addr,element,name) \
03550 { \
03551 name **f = (name**)(addr); \
03552 int n = element->GetArrayLength() ? element->GetArrayLength() : 1;\
03553 for(int j=0;j<n;j++) { \
03554 delete [] f[j]; \
03555 f[j] = 0; \
03556 } \
03557 }
03558
03559
03560 void TStreamerInfo::DestructorImpl(void* obj, Bool_t dtorOnly)
03561 {
03562
03563
03564
03565
03566 R__ASSERT(obj != 0);
03567
03568 char *p = (char*)obj;
03569
03570 Int_t nelements = fElements->GetEntriesFast();
03571
03572 for (Int_t elenum = nelements - 1; elenum >= 0; --elenum) {
03573 TStreamerElement* ele = (TStreamerElement*) fElements->UncheckedAt(elenum);
03574 if (ele->GetOffset() == kMissing) continue;
03575 char* eaddr = p + ele->GetOffset();
03576
03577
03578 Int_t etype = ele->GetType();
03579
03580 switch(etype) {
03581 case TStreamerInfo::kOffsetP + TStreamerInfo::kBool: DeleteBasicPointer(eaddr,ele,Bool_t); continue;
03582 case TStreamerInfo::kOffsetP + TStreamerInfo::kChar: DeleteBasicPointer(eaddr,ele,Char_t); continue;
03583 case TStreamerInfo::kOffsetP + TStreamerInfo::kShort: DeleteBasicPointer(eaddr,ele,Short_t); continue;
03584 case TStreamerInfo::kOffsetP + TStreamerInfo::kInt: DeleteBasicPointer(eaddr,ele,Int_t); continue;
03585 case TStreamerInfo::kOffsetP + TStreamerInfo::kLong: DeleteBasicPointer(eaddr,ele,Long_t); continue;
03586 case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: DeleteBasicPointer(eaddr,ele,Long64_t); continue;
03587 case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat16:
03588 case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat: DeleteBasicPointer(eaddr,ele,Float_t); continue;
03589 case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble32:
03590 case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: DeleteBasicPointer(eaddr,ele,Double_t); continue;
03591 case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar: DeleteBasicPointer(eaddr,ele,UChar_t); continue;
03592 case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: DeleteBasicPointer(eaddr,ele,UShort_t); continue;
03593 case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt: DeleteBasicPointer(eaddr,ele,UInt_t); continue;
03594 case TStreamerInfo::kOffsetP + TStreamerInfo::kULong: DeleteBasicPointer(eaddr,ele,ULong_t); continue;
03595 case TStreamerInfo::kOffsetP + TStreamerInfo::kULong64:DeleteBasicPointer(eaddr,ele,ULong64_t); continue;
03596 }
03597
03598
03599
03600 TClass* cle = ele->GetClassPointer();
03601 if (!cle) continue;
03602
03603
03604 if (etype == kObjectp || etype == kAnyp) {
03605
03606 Int_t len = ele->GetArrayLength();
03607 if (!len) {
03608 len = 1;
03609 }
03610 void** r = (void**) eaddr;
03611 for (Int_t j = len - 1; j >= 0; --j) {
03612 if (r[j]) {
03613 cle->Destructor(r[j]);
03614 r[j] = 0;
03615 }
03616 }
03617 }
03618
03619 if ((etype == kObjectP || etype == kAnyP || etype == kSTLp) && !ele->TestBit(TStreamerElement::kDoNotDelete)) {
03620
03621 Int_t len = ele->GetArrayLength();
03622 if (!len) {
03623 len = 1;
03624 }
03625 void** r = (void**) eaddr;
03626 for (Int_t j = len - 1; j >= 0; --j) {
03627 if (r[j]) {
03628 cle->Destructor(r[j]);
03629 r[j] = 0;
03630 }
03631 }
03632 }
03633
03634 if (etype == kObject || etype == kAny || etype == kBase ||
03635 etype == kTObject || etype == kTString || etype == kTNamed) {
03636
03637 cle->Destructor(eaddr, kTRUE);
03638 }
03639
03640 if (etype == kSTL) {
03641
03642 TVirtualCollectionProxy *pr = cle->GetCollectionProxy();
03643 if (!pr) {
03644 cle->Destructor(eaddr, kTRUE);
03645 } else {
03646 if (ele->TestBit(TStreamerElement::kDoNotDelete)) {
03647 TVirtualCollectionProxy::TPushPop env(cle->GetCollectionProxy(), eaddr);
03648 cle->GetCollectionProxy()->Clear();
03649 pr->Destructor(eaddr, kTRUE);
03650 } else {
03651 pr->Destructor(eaddr, kTRUE);
03652 }
03653 }
03654 }
03655
03656 if (etype == kObject + kOffsetL || etype == kAny + kOffsetL ||
03657 etype == kTObject + kOffsetL || etype == kTString + kOffsetL ||
03658 etype == kTNamed + kOffsetL || etype == kSTL + kOffsetL) {
03659
03660
03661 Int_t len = ele->GetArrayLength();
03662 Int_t size = cle->Size();
03663 char* r = eaddr + (size * (len - 1));
03664 for (Int_t j = len - 1; j >= 0; --j, r -= size) {
03665 cle->Destructor(r, kTRUE);
03666 }
03667 }
03668 }
03669
03670 if (!dtorOnly) {
03671 delete[] p;
03672 }
03673 --fLiveCount;
03674 }
03675
03676
03677 void TStreamerInfo::Destructor(void* obj, Bool_t dtorOnly)
03678 {
03679
03680
03681
03682
03683
03684
03685 if (obj == 0) return;
03686
03687 char* p = (char*) obj;
03688
03689 if (!dtorOnly && fNVirtualInfoLoc) {
03690
03691
03692 TStreamerInfo *allocator = *(TStreamerInfo**)(p + fVirtualInfoLoc[0]);
03693 if (allocator != this) {
03694
03695 Int_t baseoffset = allocator->GetClass()->GetBaseClassOffset(GetClass());
03696
03697 p -= baseoffset;
03698 allocator->DestructorImpl(p, kFALSE);
03699 return;
03700 }
03701 }
03702 DestructorImpl(p, dtorOnly);
03703 }
03704
03705
03706 void TStreamerInfo::DeleteArray(void* ary, Bool_t dtorOnly)
03707 {
03708
03709
03710
03711 if (ary == 0) return;
03712
03713
03714
03715 Long_t* r = (Long_t*) ary;
03716 Long_t arrayLen = r[-1];
03717 Long_t size = r[-2];
03718 char* memBegin = (char*) &r[-2];
03719
03720 char* p = ((char*) ary) + ((arrayLen - 1) * size);
03721 for (Long_t cnt = 0; cnt < arrayLen; ++cnt, p -= size) {
03722
03723 Destructor(p, kTRUE);
03724 }
03725
03726 if (!dtorOnly) {
03727 delete[] memBegin;
03728 }
03729 }
03730
03731
03732 void TStreamerInfo::PrintValue(const char *name, char *pointer, Int_t i, Int_t len, Int_t lenmax) const
03733 {
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743 char *ladd;
03744 Int_t atype,aleng;
03745 printf(" %-15s = ",name);
03746
03747 TStreamerElement * aElement = 0;
03748 Int_t *count = 0;
03749 if (len >= 0) {
03750 ladd = pointer;
03751 atype = i;
03752 aleng = len;
03753 } else {
03754 if (i < 0) {
03755 if (pointer==0) {
03756 printf("NULL\n");
03757 } else {
03758 static TClassRef stringClass("string");
03759 if (fClass == stringClass) {
03760 std::string *st = (std::string*)(pointer);
03761 printf("%s\n",st->c_str());
03762 } else if (fClass == TString::Class()) {
03763 TString *st = (TString*)(pointer);
03764 printf("%s\n",st->Data());
03765 } else {
03766 printf("(%s*)0x%lx\n",GetName(),(ULong_t)pointer);
03767 }
03768 }
03769 return;
03770 }
03771 ladd = pointer + fOffset[i];
03772 atype = fNewType[i];
03773 aleng = fLength[i];
03774 aElement = (TStreamerElement*)fElem[i];
03775 count = (Int_t*)(pointer+fMethod[i]);
03776 }
03777 if (aleng > lenmax) aleng = lenmax;
03778
03779 PrintValueAux(ladd,atype,aElement,aleng,count);
03780 printf("\n");
03781 }
03782
03783
03784 void TStreamerInfo::PrintValueClones(const char *name, TClonesArray *clones, Int_t i, Int_t eoffset, Int_t lenmax) const
03785 {
03786
03787
03788 if (!clones) {printf(" %-15s = \n",name); return;}
03789 printf(" %-15s = ",name);
03790 Int_t nc = clones->GetEntriesFast();
03791 if (nc > lenmax) nc = lenmax;
03792
03793 Int_t offset = eoffset + fOffset[i];
03794 TStreamerElement *aElement = (TStreamerElement*)fElem[i];
03795 int aleng = fLength[i];
03796 if (aleng > lenmax) aleng = lenmax;
03797
03798 for (Int_t k=0;k < nc;k++) {
03799 char *pointer = (char*)clones->UncheckedAt(k);
03800 char *ladd = pointer+offset;
03801 Int_t *count = (Int_t*)(pointer+fMethod[i]);
03802 PrintValueAux(ladd,fNewType[i],aElement, aleng, count);
03803 if (k < nc-1) printf(", ");
03804 }
03805 printf("\n");
03806 }
03807
03808
03809 void TStreamerInfo::PrintValueSTL(const char *name, TVirtualCollectionProxy *cont, Int_t i, Int_t eoffset, Int_t lenmax) const
03810 {
03811
03812
03813 if (!cont) {printf(" %-15s = \n",name); return;}
03814 printf(" %-15s = ",name);
03815 Int_t nc = cont->Size();
03816 if (nc > lenmax) nc = lenmax;
03817
03818 Int_t offset = eoffset + fOffset[i];
03819 TStreamerElement *aElement = (TStreamerElement*)fElem[i];
03820 int aleng = fLength[i];
03821 if (aleng > lenmax) aleng = lenmax;
03822
03823 for (Int_t k=0;k < nc;k++) {
03824 char *pointer = (char*)cont->At(k);
03825 char *ladd = pointer+offset;
03826 Int_t *count = (Int_t*)(pointer+fMethod[i]);
03827 PrintValueAux(ladd,fNewType[i],aElement, aleng, count);
03828 if (k < nc-1) printf(", ");
03829 }
03830 printf("\n");
03831 }
03832
03833
03834 void TStreamerInfo::Streamer(TBuffer &R__b)
03835 {
03836
03837
03838 UInt_t R__s, R__c;
03839 if (R__b.IsReading()) {
03840 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
03841 fOldVersion = R__v;
03842 if (R__v > 1) {
03843
03844 R__b.ClassBegin(TStreamerInfo::Class(), R__v);
03845 R__b.ClassMember("TNamed");
03846 TNamed::Streamer(R__b);
03847 fName = TClassEdit::GetLong64_Name( fName.Data() ).c_str();
03848 R__b.ClassMember("fCheckSum","UInt_t");
03849 R__b >> fCheckSum;
03850 R__b.ClassMember("fClassVersion","Int_t");
03851 R__b >> fClassVersion;
03852 fOnFileClassVersion = fClassVersion;
03853 R__b.ClassMember("fElements","TObjArray*");
03854 R__b >> fElements;
03855 R__b.ClassEnd(TStreamerInfo::Class());
03856 R__b.SetBufferOffset(R__s+R__c+sizeof(UInt_t));
03857 ResetBit(kIsCompiled);
03858 return;
03859 }
03860
03861 TNamed::Streamer(R__b);
03862 fName = TClassEdit::GetLong64_Name( fName.Data() ).c_str();
03863 R__b >> fCheckSum;
03864 R__b >> fClassVersion;
03865 fOnFileClassVersion = fClassVersion;
03866 R__b >> fElements;
03867 R__b.CheckByteCount(R__s, R__c, TStreamerInfo::IsA());
03868 } else {
03869 R__c = R__b.WriteVersion(TStreamerInfo::IsA(), kTRUE);
03870 R__b.ClassBegin(TStreamerInfo::Class());
03871 R__b.ClassMember("TNamed");
03872 TNamed::Streamer(R__b);
03873 R__b.ClassMember("fCheckSum","UInt_t");
03874 R__b << fCheckSum;
03875 R__b.ClassMember("fClassVersion","Int_t");
03876 R__b << ((fClassVersion > 0) ? fClassVersion : -fClassVersion);
03877
03878
03879
03880
03881 R__b.ClassMember("fElements","TObjArray*");
03882 #if NOTYET
03883 if (has_no_artificial_member) {
03884 R__b << fElements;
03885 } else
03886 #endif
03887 {
03888 R__LOCKGUARD(gCINTMutex);
03889 Int_t nobjects = fElements->GetEntriesFast();
03890 TObjArray store( *fElements );
03891 TStreamerElement *el;
03892 for (Int_t i = 0; i < nobjects; i++) {
03893 el = (TStreamerElement*)fElements->UncheckedAt(i);
03894 if( el != 0 && (el->IsA() == TStreamerArtificial::Class() || el->TestBit(TStreamerElement::kRepeat))) {
03895 fElements->RemoveAt( i );
03896 }
03897 }
03898 fElements->Compress();
03899 R__b << fElements;
03900 R__ASSERT(!fElements->IsOwner());
03901 *fElements = store;
03902 }
03903 R__b.ClassEnd(TStreamerInfo::Class());
03904 R__b.SetByteCount(R__c, kTRUE);
03905 }
03906 }
03907
03908
03909 void TStreamerInfo::TagFile(TFile *file)
03910 {
03911
03912
03913
03914
03915 if (file) {
03916 static Bool_t onlyonce = kFALSE;
03917 if (!onlyonce) {
03918 Warning("TagFile","This function is deprecated, use TBuffer::TagStreamerInfo instead");
03919 onlyonce = kTRUE;
03920 }
03921 TArrayC *cindex = file->GetClassIndex();
03922 Int_t nindex = cindex->GetSize();
03923 if (fNumber < 0 || fNumber >= nindex) {
03924 Error("TagFile","StreamerInfo: %s number: %d out of range[0,%d] in file: %s",
03925 GetName(),fNumber,nindex,file->GetName());
03926 return;
03927 }
03928 if (cindex->fArray[fNumber] == 0) {
03929 cindex->fArray[0] = 1;
03930 cindex->fArray[fNumber] = 1;
03931 }
03932 }
03933 }
03934
03935
03936 #ifdef DOLOOP
03937 #undef DOLOOP
03938 #endif
03939 #define DOLOOP for (k = 0, pointer = arr[0]; k < narr; pointer = arr[++k])
03940
03941 namespace {
03942 static void PrintCR(int j,Int_t aleng, UInt_t ltype)
03943 {
03944 if (j == aleng-1) printf("\n");
03945 else {
03946 printf(", ");
03947 if (j%ltype == ltype-1) printf("\n ");
03948 }
03949 }
03950 }
03951
03952
03953 void TStreamerInfo::PrintValueAux(char *ladd, Int_t atype, TStreamerElement *aElement, Int_t aleng, Int_t *count)
03954 {
03955
03956
03957
03958
03959
03960
03961
03962
03963 int j;
03964
03965
03966 switch (atype) {
03967
03968 case kBool: {Bool_t *val = (Bool_t* )ladd; printf("%d" ,*val); break;}
03969 case kChar: {Char_t *val = (Char_t* )ladd; printf("%d" ,*val); break;}
03970 case kShort: {Short_t *val = (Short_t* )ladd; printf("%d" ,*val); break;}
03971 case kInt: {Int_t *val = (Int_t* )ladd; printf("%d" ,*val); break;}
03972 case kLong: {Long_t *val = (Long_t* )ladd; printf("%ld",*val); break;}
03973 case kLong64: {Long64_t *val = (Long64_t* )ladd; printf("%lld",*val); break;}
03974 case kFloat: {Float_t *val = (Float_t* )ladd; printf("%f" ,*val); break;}
03975 case kFloat16: {Float_t *val = (Float_t* )ladd; printf("%f" ,*val); break;}
03976 case kDouble: {Double_t *val = (Double_t* )ladd; printf("%g" ,*val); break;}
03977 case kDouble32: {Double_t *val = (Double_t* )ladd; printf("%g" ,*val); break;}
03978 case kUChar: {UChar_t *val = (UChar_t* )ladd; printf("%u" ,*val); break;}
03979 case kUShort: {UShort_t *val = (UShort_t* )ladd; printf("%u" ,*val); break;}
03980 case kUInt: {UInt_t *val = (UInt_t* )ladd; printf("%u" ,*val); break;}
03981 case kULong: {ULong_t *val = (ULong_t* )ladd; printf("%lu",*val); break;}
03982 case kULong64: {ULong64_t *val = (ULong64_t*)ladd; printf("%llu",*val); break;}
03983 case kBits: {UInt_t *val = (UInt_t* )ladd; printf("%d" ,*val); break;}
03984
03985
03986 case kOffsetL + kBool: {Bool_t *val = (Bool_t* )ladd; for(j=0;j<aleng;j++) { printf("%c " ,val[j]); PrintCR(j,aleng,20); } break;}
03987 case kOffsetL + kChar: {Char_t *val = (Char_t* )ladd; for(j=0;j<aleng;j++) { printf("%c " ,val[j]); PrintCR(j,aleng,20); } break;}
03988 case kOffsetL + kShort: {Short_t *val = (Short_t* )ladd; for(j=0;j<aleng;j++) { printf("%d " ,val[j]); PrintCR(j,aleng,10); } break;}
03989 case kOffsetL + kInt: {Int_t *val = (Int_t* )ladd; for(j=0;j<aleng;j++) { printf("%d " ,val[j]); PrintCR(j,aleng,10); } break;}
03990 case kOffsetL + kLong: {Long_t *val = (Long_t* )ladd; for(j=0;j<aleng;j++) { printf("%ld ",val[j]); PrintCR(j,aleng, 5); } break;}
03991 case kOffsetL + kLong64: {Long64_t *val = (Long64_t* )ladd; for(j=0;j<aleng;j++) { printf("%lld ",val[j]);PrintCR(j,aleng, 5); } break;}
03992 case kOffsetL + kFloat: {Float_t *val = (Float_t* )ladd; for(j=0;j<aleng;j++) { printf("%f " ,val[j]); PrintCR(j,aleng, 5); } break;}
03993 case kOffsetL + kFloat16: {Float_t *val = (Float_t* )ladd; for(j=0;j<aleng;j++) { printf("%f " ,val[j]); PrintCR(j,aleng, 5); } break;}
03994 case kOffsetL + kDouble: {Double_t *val = (Double_t* )ladd; for(j=0;j<aleng;j++) { printf("%g " ,val[j]); PrintCR(j,aleng, 5); } break;}
03995 case kOffsetL + kDouble32:{Double_t *val = (Double_t* )ladd; for(j=0;j<aleng;j++) { printf("%g " ,val[j]); PrintCR(j,aleng, 5); } break;}
03996 case kOffsetL + kUChar: {UChar_t *val = (UChar_t* )ladd; for(j=0;j<aleng;j++) { printf("%u " ,val[j]); PrintCR(j,aleng,20); } break;}
03997 case kOffsetL + kUShort: {UShort_t *val = (UShort_t* )ladd; for(j=0;j<aleng;j++) { printf("%u " ,val[j]); PrintCR(j,aleng,10); } break;}
03998 case kOffsetL + kUInt: {UInt_t *val = (UInt_t* )ladd; for(j=0;j<aleng;j++) { printf("%u " ,val[j]); PrintCR(j,aleng, 5); } break;}
03999 case kOffsetL + kULong: {ULong_t *val = (ULong_t* )ladd; for(j=0;j<aleng;j++) { printf("%lu ",val[j]); PrintCR(j,aleng, 5); } break;}
04000 case kOffsetL + kULong64: {ULong64_t *val = (ULong64_t*)ladd; for(j=0;j<aleng;j++) { printf("%llu ",val[j]);PrintCR(j,aleng, 5); } break;}
04001 case kOffsetL + kBits: {UInt_t *val = (UInt_t* )ladd; for(j=0;j<aleng;j++) { printf("%d " ,val[j]); PrintCR(j,aleng, 5); } break;}
04002
04003
04004 case kOffsetP + kBool: {Bool_t **val = (Bool_t** )ladd; for(j=0;j<*count;j++) { printf("%d " ,(*val)[j]); PrintCR(j,aleng,20); } break;}
04005 case kOffsetP + kChar: {Char_t **val = (Char_t** )ladd; for(j=0;j<*count;j++) { printf("%d " ,(*val)[j]); PrintCR(j,aleng,20); } break;}
04006 case kOffsetP + kShort: {Short_t **val = (Short_t** )ladd; for(j=0;j<*count;j++) { printf("%d " ,(*val)[j]); PrintCR(j,aleng,10); } break;}
04007 case kOffsetP + kInt: {Int_t **val = (Int_t** )ladd; for(j=0;j<*count;j++) { printf("%d " ,(*val)[j]); PrintCR(j,aleng,10); } break;}
04008 case kOffsetP + kLong: {Long_t **val = (Long_t** )ladd; for(j=0;j<*count;j++) { printf("%ld ",(*val)[j]); PrintCR(j,aleng, 5); } break;}
04009 case kOffsetP + kLong64: {Long64_t **val = (Long64_t**)ladd; for(j=0;j<*count;j++) { printf("%lld ",(*val)[j]); PrintCR(j,aleng, 5); } break;}
04010 case kOffsetP + kFloat: {Float_t **val = (Float_t** )ladd; for(j=0;j<*count;j++) { printf("%f " ,(*val)[j]); PrintCR(j,aleng, 5); } break;}
04011 case kOffsetP + kFloat16: {Float_t **val = (Float_t** )ladd; for(j=0;j<*count;j++) { printf("%f " ,(*val)[j]); PrintCR(j,aleng, 5); } break;}
04012 case kOffsetP + kDouble: {Double_t **val = (Double_t**)ladd; for(j=0;j<*count;j++) { printf("%g " ,(*val)[j]); PrintCR(j,aleng, 5); } break;}
04013 case kOffsetP + kDouble32:{Double_t **val = (Double_t**)ladd; for(j=0;j<*count;j++) { printf("%g " ,(*val)[j]); PrintCR(j,aleng, 5); } break;}
04014 case kOffsetP + kUChar: {UChar_t **val = (UChar_t** )ladd; for(j=0;j<*count;j++) { printf("%u " ,(*val)[j]); PrintCR(j,aleng,20); } break;}
04015 case kOffsetP + kUShort: {UShort_t **val = (UShort_t**)ladd; for(j=0;j<*count;j++) { printf("%u " ,(*val)[j]); PrintCR(j,aleng,10); } break;}
04016 case kOffsetP + kUInt: {UInt_t **val = (UInt_t** )ladd; for(j=0;j<*count;j++) { printf("%u " ,(*val)[j]); PrintCR(j,aleng, 5); } break;}
04017 case kOffsetP + kULong: {ULong_t **val = (ULong_t** )ladd; for(j=0;j<*count;j++) { printf("%lu ",(*val)[j]); PrintCR(j,aleng, 5); } break;}
04018 case kOffsetP + kULong64: {ULong64_t**val = (ULong64_t**)ladd; for(j=0;j<*count;j++){ printf("%llu ",(*val)[j]); PrintCR(j,aleng, 5); } break;}
04019
04020
04021 case kCounter: {Int_t *val = (Int_t*)ladd; printf("%d",*val); break;}
04022
04023 case kCharStar:{
04024 char **val = (char**)ladd;
04025 if (*val) printf("%s",*val);
04026 break;
04027 }
04028
04029 case kObjectp: {
04030 TObject **obj = (TObject**)(ladd);
04031 TStreamerObjectPointer *el = (TStreamerObjectPointer*)aElement;
04032 printf("(%s*)%lx",el ? el->GetClass()->GetName() : "unknown_type",(Long_t)(*obj));
04033 break;
04034 }
04035
04036
04037 case kObjectP: {
04038 TObject **obj = (TObject**)(ladd);
04039 TStreamerObjectPointer *el = (TStreamerObjectPointer*)aElement;
04040 printf("(%s*)%lx",el ? el->GetClass()->GetName() : "unknown_type",(Long_t)(*obj));
04041 break;
04042 }
04043
04044
04045 case kObject: {
04046 TObject *obj = (TObject*)(ladd);
04047 printf("%s",obj->GetName());
04048 break;
04049 }
04050
04051
04052 case kTString: {
04053 TString *st = (TString*)(ladd);
04054 printf("%s",st->Data());
04055 break;
04056 }
04057 case kTObject: {
04058 TObject *obj = (TObject*)(ladd);
04059 printf("%s",obj->GetName());
04060 break;
04061 }
04062 case kTNamed: {
04063 TNamed *named = (TNamed*) (ladd);
04064 printf("%s/%s",named->GetName(),named->GetTitle());
04065 break;
04066 }
04067
04068
04069 case kAnyp: {
04070 TObject **obj = (TObject**)(ladd);
04071 TStreamerObjectAnyPointer *el = (TStreamerObjectAnyPointer*)aElement;
04072 printf("(%s*)0x%lx",el ? el->GetClass()->GetName() : "unknown_type",(Long_t)(*obj));
04073 break;
04074 }
04075
04076
04077 case kAnyP: {
04078 TObject **obj = (TObject**)(ladd);
04079 TStreamerObjectAnyPointer *el = (TStreamerObjectAnyPointer*)aElement;
04080 printf("(%s*)0x%lx",el ? el->GetClass()->GetName() : "unknown_type",(Long_t)(*obj));
04081 break;
04082 }
04083
04084 case kOffsetL + kObjectp:
04085 case kOffsetL + kObjectP:
04086 case kAny: {
04087 printf("printing kAny case (%d)",atype);
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097 break;
04098 }
04099
04100 case kBase: {
04101 printf("printing kBase case (%d)",atype);
04102
04103 break;
04104 }
04105
04106 case kOffsetL + kObject:
04107 case kOffsetL + kTString:
04108 case kOffsetL + kTObject:
04109 case kOffsetL + kTNamed:
04110 case kStreamer: {
04111 printf("printing kStreamer case (%d)",atype);
04112
04113
04114
04115
04116
04117
04118
04119
04120
04121
04122 break;
04123 }
04124
04125 case kStreamLoop: {
04126 printf("printing kStreamLoop case (%d)",atype);
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
04138 break;
04139 }
04140 case kSTL: {
04141 if (aElement) {
04142 static TClassRef stringClass("string");
04143 if (ladd && aElement->GetClass() == stringClass) {
04144 std::string *st = (std::string*)(ladd);
04145 printf("%s",st->c_str());
04146 } else {
04147 printf("(%s*)0x%lx",aElement->GetClass()->GetName(),(Long_t)(ladd));
04148 }
04149 } else {
04150 printf("(unknown_type*)0x%lx",(Long_t)(ladd));
04151 }
04152 break;
04153 }
04154 }
04155 }
04156
04157
04158 void TStreamerInfo::Update(const TClass *oldcl, TClass *newcl)
04159 {
04160
04161
04162
04163 TStreamerElement *element;
04164 TIter nextElement(GetElements());
04165 while ((element = (TStreamerElement*)nextElement())) {
04166 element->Update(oldcl,newcl);
04167 }
04168 for (Int_t i=0;i < fNdata;i++) {
04169 fComp[i].Update(oldcl,newcl);
04170 }
04171 }
04172
04173
04174 void TStreamerInfo::TCompInfo::Update(const TClass *oldcl, TClass *newcl)
04175 {
04176
04177
04178 if (fClass == oldcl)
04179 fClass = newcl;
04180 else if (fClass == 0)
04181 fClass =TClass::GetClass(fClassName);
04182 }
04183
04184
04185
04186
04187
04188
04189 TVirtualCollectionProxy*
04190 TStreamerInfo::GenEmulatedProxy(const char* class_name)
04191 {
04192
04193
04194 return TCollectionProxyFactory::GenEmulatedProxy(class_name);
04195 }
04196
04197
04198 TClassStreamer*
04199 TStreamerInfo::GenEmulatedClassStreamer(const char* class_name)
04200 {
04201
04202
04203 return TCollectionProxyFactory::GenEmulatedClassStreamer(class_name);
04204 }
04205
04206
04207 TVirtualCollectionProxy*
04208 TStreamerInfo::GenExplicitProxy( const ::ROOT::TCollectionProxyInfo &info, TClass *cl )
04209 {
04210
04211
04212 return TCollectionProxyFactory::GenExplicitProxy(info, cl);
04213 }
04214
04215
04216 TClassStreamer*
04217 TStreamerInfo::GenExplicitClassStreamer( const ::ROOT::TCollectionProxyInfo &info, TClass *cl )
04218 {
04219
04220
04221 return TCollectionProxyFactory::GenExplicitClassStreamer(info, cl);
04222 }