00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TStreamerInfo.h"
00013 #include "TStreamerInfoActions.h"
00014 #include "TROOT.h"
00015 #include "TStreamerElement.h"
00016 #include "TVirtualMutex.h"
00017 #include "TInterpreter.h"
00018 #include "TError.h"
00019 #include "TVirtualArray.h"
00020 #include "TBufferFile.h"
00021 #include "TMemberStreamer.h"
00022 #include "TError.h"
00023 #include "TClassEdit.h"
00024 #include "TVirtualCollectionIterators.h"
00025
00026 static const Int_t kRegrouped = TStreamerInfo::kOffsetL;
00027
00028
00029
00030
00031
00032
00033
00034 using namespace TStreamerInfoActions;
00035
00036 namespace TStreamerInfoActions
00037 {
00038 void TConfiguration::AddToOffset(Int_t delta)
00039 {
00040
00041
00042
00043 fOffset += delta;
00044 }
00045
00046 void TConfiguredAction::PrintDebug(TBuffer &buf, void *addr) const
00047 {
00048
00049
00050
00051 if (fConfiguration) fConfiguration->PrintDebug(buf,addr);
00052 }
00053
00054 void TConfiguration::Print() const
00055 {
00056
00057
00058
00059 TStreamerInfo *info = (TStreamerInfo*)fInfo;
00060 TStreamerElement *aElement = (TStreamerElement*)info->GetElems()[fElemId];
00061
00062 printf("StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
00063 " %s, offset=%d\n",
00064 info->GetClass()->GetName(), aElement->GetName(), fElemId, info->GetTypes()[fElemId],
00065 aElement->ClassName(), fOffset);
00066 }
00067
00068 void TConfiguration::PrintDebug(TBuffer &buf, void *addr) const
00069 {
00070
00071
00072 if (gDebug > 1) {
00073
00074 TStreamerInfo *info = (TStreamerInfo*)fInfo;
00075 TStreamerElement *aElement = (TStreamerElement*)info->GetElems()[fElemId];
00076
00077 printf("StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
00078 " %s, bufpos=%d, arr=%p, offset=%d\n",
00079 info->GetClass()->GetName(), aElement->GetName(), fElemId, info->GetTypes()[fElemId],
00080 aElement->ClassName(), buf.Length(), addr, fOffset);
00081 }
00082 }
00083
00084 void TLoopConfiguration::Print() const
00085 {
00086
00087
00088 printf("TLoopConfiguration: unconfigured\n");
00089 }
00090
00091
00092 struct TGenericConfiguration : TConfiguration {
00093
00094
00095 public:
00096 TGenericConfiguration(TVirtualStreamerInfo *info, UInt_t id, Int_t offset = 0) : TConfiguration(info,id,offset) {};
00097 void PrintDebug(TBuffer &, void *) const {
00098
00099 }
00100 };
00101
00102
00103 Int_t GenericAction(TBuffer &buf, void *addr, const TConfiguration *config)
00104 {
00105 char *obj = (char*)addr;
00106 TGenericConfiguration *conf = (TGenericConfiguration*)config;
00107 return ((TStreamerInfo*)conf->fInfo)->ReadBuffer(buf, &obj, conf->fElemId, 1, config->fOffset, 2);
00108 }
00109
00110 template <typename T>
00111 inline Int_t ReadBasicType(TBuffer &buf, void *addr, const TConfiguration *config)
00112 {
00113 T *x = (T*)( ((char*)addr) + config->fOffset );
00114
00115 buf >> *x;
00116 return 0;
00117 }
00118
00119 class TConfWithFactor : public TConfiguration {
00120
00121 public:
00122 Double_t fFactor;
00123 Double_t fXmin;
00124 TConfWithFactor(TVirtualStreamerInfo *info, UInt_t id, Int_t offset, Double_t factor, Double_t xmin) : TConfiguration(info,id,offset),fFactor(factor),fXmin(xmin) {};
00125 virtual TConfiguration *Copy() { return new TConfWithFactor(*this); }
00126 };
00127
00128 template <typename T>
00129 inline Int_t ReadBasicType_WithFactor(TBuffer &buf, void *addr, const TConfiguration *config)
00130 {
00131
00132
00133
00134 TConfWithFactor *conf = (TConfWithFactor *)config;
00135 buf.ReadWithFactor((T*)( ((char*)addr) + config->fOffset ), conf->fFactor, conf->fXmin);
00136 return 0;
00137 }
00138
00139 class TConfNoFactor : public TConfiguration {
00140
00141 public:
00142 Int_t fNbits;
00143 TConfNoFactor(TVirtualStreamerInfo *info, UInt_t id, Int_t offset, Int_t nbits) : TConfiguration(info,id,offset),fNbits(nbits) {};
00144 virtual TConfiguration *Copy() { return new TConfNoFactor(*this); }
00145 };
00146
00147 template <typename T>
00148 inline Int_t ReadBasicType_NoFactor(TBuffer &buf, void *addr, const TConfiguration *config)
00149 {
00150
00151
00152 TConfNoFactor *conf = (TConfNoFactor *)config;
00153 Int_t nbits = conf->fNbits;
00154
00155 buf.ReadWithNbits( (T*)( ((char*)addr) + config->fOffset ), nbits );
00156 return 0;
00157 }
00158
00159 inline Int_t ReadTString(TBuffer &buf, void *addr, const TConfiguration *config)
00160 {
00161
00162
00163
00164
00165 ((TString*)(((char*)addr)+config->fOffset))->TString::Streamer(buf);
00166 return 0;
00167 }
00168
00169 inline Int_t ReadTObject(TBuffer &buf, void *addr, const TConfiguration *config)
00170 {
00171
00172
00173
00174
00175 ((TObject*)(((char*)addr)+config->fOffset))->TObject::Streamer(buf);
00176 return 0;
00177 }
00178
00179 inline Int_t ReadTNamed(TBuffer &buf, void *addr, const TConfiguration *config)
00180 {
00181
00182
00183
00184
00185
00186
00187 static const TClass *TNamed_cl = TNamed::Class();
00188 return buf.ReadClassBuffer(TNamed_cl,(((char*)addr)+config->fOffset));
00189 }
00190
00191 class TConfigSTL : public TConfiguration {
00192
00193 private:
00194 void Init() {
00195 TVirtualCollectionProxy *proxy = fNewClass->GetCollectionProxy();
00196 if (proxy) {
00197 fCreateIterators = proxy->GetFunctionCreateIterators();
00198 fCopyIterator = proxy->GetFunctionCopyIterator();
00199 fDeleteIterator = proxy->GetFunctionDeleteIterator();
00200 fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators();
00201 }
00202 }
00203
00204 public:
00205 TClass *fOldClass;
00206 TClass *fNewClass;
00207 TMemberStreamer *fStreamer;
00208 const char *fTypeName;
00209 bool fIsSTLBase;
00210
00211 TVirtualCollectionProxy::CreateIterators_t fCreateIterators;
00212 TVirtualCollectionProxy::CopyIterator_t fCopyIterator;
00213 TVirtualCollectionProxy::DeleteIterator_t fDeleteIterator;
00214 TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators;
00215
00216 TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, Int_t offset, UInt_t length, TClass *oldClass, const char *type_name, Bool_t isbase) :
00217 TConfiguration(info,id,offset,length), fOldClass(oldClass), fNewClass(oldClass), fTypeName(type_name), fIsSTLBase(isbase),
00218 fCreateIterators(0), fCopyIterator(0), fDeleteIterator(0), fDeleteTwoIterators(0) { Init(); }
00219
00220 TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, Int_t offset, UInt_t length, TClass *oldClass, TClass *newClass, const char *type_name, Bool_t isbase) :
00221 TConfiguration(info,id,offset,length), fOldClass(oldClass), fNewClass(newClass), fTypeName(type_name), fIsSTLBase(isbase),
00222 fCreateIterators(0), fCopyIterator(0), fDeleteIterator(0), fDeleteTwoIterators(0) { Init(); }
00223
00224 TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, Int_t offset, UInt_t length, TClass *oldClass, TMemberStreamer* streamer, const char *type_name, Bool_t isbase) :
00225 TConfiguration(info,id,offset,length), fOldClass(oldClass), fNewClass(oldClass), fStreamer(streamer), fTypeName(type_name), fIsSTLBase(isbase),
00226 fCreateIterators(0), fCopyIterator(0), fDeleteIterator(0), fDeleteTwoIterators(0) { Init(); }
00227
00228 TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, Int_t offset, UInt_t length, TClass *oldClass, TClass *newClass, TMemberStreamer* streamer, const char *type_name, Bool_t isbase) :
00229 TConfiguration(info,id,offset,length), fOldClass(oldClass), fNewClass(newClass), fStreamer(streamer), fTypeName(type_name), fIsSTLBase(isbase),
00230 fCreateIterators(0), fCopyIterator(0), fDeleteIterator(0), fDeleteTwoIterators(0) { Init(); }
00231
00232 virtual TConfiguration *Copy() { return new TConfigSTL(*this); }
00233 };
00234
00235 class TVectorLoopConfig : public TLoopConfiguration {
00236
00237 protected:
00238 public:
00239 Long_t fIncrement;
00240 public:
00241 TVectorLoopConfig(Long_t increment) : fIncrement(increment) {};
00242
00243 virtual ~TVectorLoopConfig() {};
00244 void Print() const
00245 {
00246 printf("TVectorLoopConfig: increment=%ld\n",fIncrement);
00247 }
00248
00249 void* GetFirstAddress(void *start, const void * ) const
00250 {
00251
00252
00253 return start;
00254 }
00255
00256 virtual TLoopConfiguration* Copy() { return new TVectorLoopConfig(*this); }
00257 };
00258
00259 class TAssocLoopConfig : public TLoopConfiguration {
00260
00261 protected:
00262 public:
00263 TVirtualCollectionProxy *fProxy;
00264 public:
00265 TAssocLoopConfig(TVirtualCollectionProxy *proxy) : fProxy(proxy) {};
00266
00267 virtual ~TAssocLoopConfig() {};
00268 void Print() const
00269 {
00270 printf("TAssocLoopConfig: proxy=%s\n",fProxy->GetCollectionClass()->GetName());
00271 }
00272 virtual TLoopConfiguration* Copy() { return new TAssocLoopConfig(*this); }
00273
00274 void* GetFirstAddress(void *start, const void * ) const
00275 {
00276
00277
00278 R__ASSERT(0);
00279
00280
00281
00282
00283
00284
00285 return start;
00286 }
00287 };
00288
00289 class TGenericLoopConfig : public TLoopConfiguration {
00290
00291 private:
00292 void Init() {
00293 if (fProxy) {
00294 if (fProxy->HasPointers()) {
00295 fNext = TVirtualCollectionPtrIterators::Next;
00296 fCopyIterator = TVirtualCollectionPtrIterators::CopyIterator;
00297 fDeleteIterator = TVirtualCollectionPtrIterators::DeleteIterator;
00298 } else {
00299 fNext = fProxy->GetFunctionNext();
00300 fCopyIterator = fProxy->GetFunctionCopyIterator();
00301 fDeleteIterator = fProxy->GetFunctionDeleteIterator();
00302 }
00303 }
00304 }
00305 public:
00306 TVirtualCollectionProxy *fProxy;
00307 TVirtualCollectionProxy::Next_t fNext;
00308 TVirtualCollectionProxy::CopyIterator_t fCopyIterator;
00309 TVirtualCollectionProxy::DeleteIterator_t fDeleteIterator;
00310
00311 TGenericLoopConfig(TVirtualCollectionProxy *proxy) : fProxy(proxy), fNext(0), fCopyIterator(0), fDeleteIterator(0)
00312 {
00313 Init();
00314 }
00315 virtual ~TGenericLoopConfig() {};
00316 void Print() const
00317 {
00318 printf("TGenericLoopConfig: proxy=%s\n",fProxy->GetCollectionClass()->GetName());
00319 }
00320 virtual TLoopConfiguration* Copy() { return new TGenericLoopConfig(*this); }
00321
00322 void* GetFirstAddress(void *start_collection, const void *end_collection) const
00323 {
00324
00325
00326 char iterator[TVirtualCollectionProxy::fgIteratorArenaSize];
00327 void *iter = fCopyIterator(&iterator,start_collection);
00328 void *arr0 = fNext(iter,end_collection);
00329 if (iter != &iterator[0]) {
00330 fDeleteIterator(iter);
00331 }
00332 return arr0;
00333 }
00334 };
00335
00336 inline void ReadSTLMemberWiseSameClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
00337 {
00338
00339
00340 TConfigSTL *config = (TConfigSTL*)conf;
00341 vers &= ~( TBufferFile::kStreamedMemberWise );
00342
00343 if( vers >= 8 ) {
00344
00345 TClass *oldClass = config->fOldClass;
00346
00347 TClass *valueClass = oldClass->GetCollectionProxy()->GetValueClass();
00348 UInt_t startDummy, countDummy;
00349 Version_t vClVersion = buf.ReadVersion( &startDummy, &countDummy, valueClass );
00350
00351 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
00352 TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)addr );
00353 Int_t nobjects;
00354 buf.ReadInt(nobjects);
00355 void* alternative = oldProxy->Allocate(nobjects,true);
00356 if (nobjects) {
00357 TActionSequence *actions = oldProxy->GetReadMemberWiseActions( vClVersion );
00358
00359 char startbuf[TVirtualCollectionProxy::fgIteratorArenaSize];
00360 char endbuf[TVirtualCollectionProxy::fgIteratorArenaSize];
00361 void *begin = &(startbuf[0]);
00362 void *end = &(endbuf[0]);
00363 config->fCreateIterators(alternative, &begin, &end );
00364
00365
00366 buf.ReadSequence(*actions, begin, end);
00367 if (begin != &(startbuf[0])) {
00368
00369 config->fDeleteTwoIterators(begin,end);
00370 }
00371 }
00372 oldProxy->Commit(alternative);
00373
00374 } else {
00375
00376 TClass *oldClass = config->fOldClass;
00377
00378 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
00379
00380 TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)addr );
00381 Int_t nobjects;
00382 buf.ReadInt(nobjects);
00383 void* env = oldProxy->Allocate(nobjects,true);
00384
00385 if (nobjects || vers < 7 ) {
00386
00387 TStreamerInfo *subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( 0 );
00388
00389 if (subinfo->IsOptimized()) {
00390 subinfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
00391 subinfo->Compile();
00392 }
00393 subinfo->ReadBuffer(buf, *oldProxy, -1, nobjects, 0, 1);
00394 }
00395 oldProxy->Commit(env);
00396 }
00397 }
00398
00399 inline void ReadArraySTLMemberWiseSameClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
00400 {
00401
00402
00403 TConfigSTL *config = (TConfigSTL*)conf;
00404 vers &= ~( TBufferFile::kStreamedMemberWise );
00405
00406 if( vers >= 8 ) {
00407
00408 TClass *oldClass = config->fOldClass;
00409
00410 TClass *valueClass = oldClass->GetCollectionProxy()->GetValueClass();
00411 UInt_t startDummy, countDummy;
00412 Version_t vClVersion = buf.ReadVersion( &startDummy, &countDummy, valueClass );
00413
00414 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
00415 TActionSequence *actions = oldProxy->GetReadMemberWiseActions( vClVersion );
00416
00417 int objectSize = oldClass->Size();
00418 char *obj = (char*)addr;
00419 char *endobj = obj + conf->fLength*objectSize;
00420
00421 for(; obj<endobj; obj+=objectSize) {
00422 Int_t nobjects;
00423 buf.ReadInt(nobjects);
00424 TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)obj );
00425 void* alternative = oldProxy->Allocate(nobjects,true);
00426 if (nobjects) {
00427 char startbuf[TVirtualCollectionProxy::fgIteratorArenaSize];
00428 char endbuf[TVirtualCollectionProxy::fgIteratorArenaSize];
00429 void *begin = &(startbuf[0]);
00430 void *end = &(endbuf[0]);
00431 config->fCreateIterators(alternative, &begin, &end );
00432
00433
00434 buf.ReadSequence(*actions, begin, end);
00435 if (begin != &(startbuf[0])) {
00436
00437 config->fDeleteTwoIterators(begin,end);
00438 }
00439 }
00440 oldProxy->Commit(alternative);
00441 }
00442
00443 } else {
00444
00445 TClass *oldClass = config->fOldClass;
00446
00447 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
00448
00449 int objectSize = oldClass->Size();
00450 char *obj = (char*)addr;
00451 char *endobj = obj + conf->fLength*objectSize;
00452
00453 for(; obj<endobj; obj+=objectSize) {
00454 TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)obj );
00455 Int_t nobjects;
00456 buf.ReadInt(nobjects);
00457 void* env = oldProxy->Allocate(nobjects,true);
00458
00459 if (nobjects || vers < 7 ) {
00460
00461 TStreamerInfo *subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( 0 );
00462
00463 if (subinfo->IsOptimized()) {
00464 subinfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
00465 subinfo->Compile();
00466 }
00467 subinfo->ReadBuffer(buf, *oldProxy, -1, nobjects, 0, 1);
00468 }
00469 oldProxy->Commit(env);
00470 }
00471 }
00472 }
00473
00474 inline void ReadSTLMemberWiseChangedClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
00475 {
00476
00477
00478 TConfigSTL *config = (TConfigSTL*)conf;
00479
00480 vers &= ~( TBufferFile::kStreamedMemberWise );
00481
00482 TClass *newClass = config->fNewClass;
00483 TClass *oldClass = config->fOldClass;
00484
00485 if( vers < 8 ) {
00486 Error( "ReadSTLMemberWiseChangedClass", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
00487 vers, buf.GetParent() ? buf.GetParent()->GetName() : "memory/socket", oldClass->GetName(), newClass->GetName() );
00488 } else {
00489
00490 UInt_t startDummy, countDummy;
00491
00492 Version_t vClVersion = buf.ReadVersion( &startDummy, &countDummy, oldClass->GetCollectionProxy()->GetValueClass() );
00493
00494 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
00495 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
00496
00497 TVirtualCollectionProxy::TPushPop helper( newProxy, (char*)addr );
00498 Int_t nobjects;
00499 buf.ReadInt(nobjects);
00500 void* alternative = newProxy->Allocate(nobjects,true);
00501 if (nobjects) {
00502 TActionSequence *actions = newProxy->GetConversionReadMemberWiseActions( oldProxy->GetValueClass(), vClVersion );
00503 char startbuf[TVirtualCollectionProxy::fgIteratorArenaSize];
00504 char endbuf[TVirtualCollectionProxy::fgIteratorArenaSize];
00505 void *begin = &(startbuf[0]);
00506 void *end = &(endbuf[0]);
00507 config->fCreateIterators( alternative, &begin, &end );
00508
00509
00510 buf.ReadSequence(*actions, begin, end);
00511 if (begin != &(startbuf[0])) {
00512
00513 config->fDeleteTwoIterators(begin,end);
00514 }
00515 }
00516 newProxy->Commit(alternative);
00517 }
00518 }
00519
00520 inline void ReadArraySTLMemberWiseChangedClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
00521 {
00522
00523
00524 TConfigSTL *config = (TConfigSTL*)conf;
00525
00526 vers &= ~( TBufferFile::kStreamedMemberWise );
00527
00528 TClass *newClass = config->fNewClass;
00529 TClass *oldClass = config->fOldClass;
00530
00531 if( vers < 8 ) {
00532 Error( "ReadSTLMemberWiseChangedClass", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
00533 vers, buf.GetParent() ? buf.GetParent()->GetName() : "memory/socket", oldClass->GetName(), newClass->GetName() );
00534 } else {
00535
00536 UInt_t startDummy, countDummy;
00537
00538 Version_t vClVersion = buf.ReadVersion( &startDummy, &countDummy, oldClass->GetCollectionProxy()->GetValueClass() );
00539
00540 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
00541 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
00542
00543 int objectSize = newClass->Size();
00544 char *obj = (char*)addr;
00545 char *endobj = obj + conf->fLength*objectSize;
00546
00547 for(; obj<endobj; obj+=objectSize) {
00548 TVirtualCollectionProxy::TPushPop helper( newProxy, (char*)obj );
00549 Int_t nobjects;
00550 buf.ReadInt(nobjects);
00551 void* alternative = newProxy->Allocate(nobjects,true);
00552 if (nobjects) {
00553 TActionSequence *actions = newProxy->GetConversionReadMemberWiseActions( oldProxy->GetValueClass(), vClVersion );
00554 char startbuf[TVirtualCollectionProxy::fgIteratorArenaSize];
00555 char endbuf[TVirtualCollectionProxy::fgIteratorArenaSize];
00556 void *begin = &(startbuf[0]);
00557 void *end = &(endbuf[0]);
00558 config->fCreateIterators( alternative, &begin, &end );
00559
00560
00561 buf.ReadSequence(*actions, begin, end);
00562 if (begin != &(startbuf[0])) {
00563
00564 config->fDeleteTwoIterators(begin,end);
00565 }
00566 }
00567 newProxy->Commit(alternative);
00568 }
00569 }
00570 }
00571
00572
00573 inline void ReadSTLObjectWiseFastArray(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t , UInt_t )
00574 {
00575 TConfigSTL *config = (TConfigSTL*)conf;
00576
00577 buf.ReadFastArray(addr,config->fNewClass,conf->fLength,(TMemberStreamer*)0,config->fOldClass);
00578 }
00579 inline void ReadSTLObjectWiseStreamer(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t , UInt_t )
00580 {
00581 TConfigSTL *config = (TConfigSTL*)conf;
00582 (*config->fStreamer)(buf,addr,conf->fLength);
00583 }
00584 inline void ReadSTLObjectWiseFastArrayV2(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers, UInt_t start)
00585 {
00586
00587
00588 TConfigSTL *config = (TConfigSTL*)conf;
00589
00590
00591 if (config->fIsSTLBase || vers == 0) {
00592 buf.SetBufferOffset(start);
00593 }
00594
00595 buf.ReadFastArray(addr,config->fNewClass,conf->fLength,(TMemberStreamer*)0,config->fOldClass);
00596 }
00597 inline void ReadSTLObjectWiseStreamerV2(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers, UInt_t start)
00598 {
00599
00600
00601 TConfigSTL *config = (TConfigSTL*)conf;
00602
00603
00604 if (config->fIsSTLBase || vers == 0) {
00605 buf.SetBufferOffset(start);
00606 }
00607 (*config->fStreamer)(buf,addr,conf->fLength);
00608 }
00609
00610 template <void (*memberwise)(TBuffer&,void *,const TConfiguration*, Version_t),
00611 void (*objectwise)(TBuffer&,void *,const TConfiguration*, Version_t, UInt_t)>
00612 inline Int_t ReadSTL(TBuffer &buf, void *addr, const TConfiguration *conf)
00613 {
00614 TConfigSTL *config = (TConfigSTL*)conf;
00615 UInt_t start, count;
00616 Version_t vers = buf.ReadVersion(&start, &count, config->fOldClass);
00617 if ( vers & TBufferFile::kStreamedMemberWise ) {
00618 memberwise(buf,((char*)addr)+config->fOffset,config, vers);
00619 } else {
00620 objectwise(buf,((char*)addr)+config->fOffset,config, vers, start);
00621 }
00622 buf.CheckByteCount(start,count,config->fTypeName);
00623 return 0;
00624 }
00625
00626 template <typename From, typename To>
00627 inline Int_t ConvertBasicType(TBuffer &buf, void *addr, const TConfiguration *config)
00628 {
00629
00630 From temp;
00631 buf >> temp;
00632 *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
00633 return 0;
00634 }
00635
00636 class TConfigurationUseCache : public TConfiguration {
00637
00638 public:
00639 TConfiguredAction fAction;
00640 Bool_t fNeedRepeat;
00641
00642 TConfigurationUseCache(TVirtualStreamerInfo *info, TConfiguredAction &action, Bool_t repeat) :
00643 TConfiguration(info,action.fConfiguration->fElemId,action.fConfiguration->fOffset),fAction(action),fNeedRepeat(repeat) {};
00644 virtual void PrintDebug(TBuffer &b, void *addr) const
00645 {
00646 if (gDebug > 1) {
00647
00648 TStreamerInfo *info = (TStreamerInfo*)fInfo;
00649 TStreamerElement *aElement = (TStreamerElement*)info->GetElems()[fElemId];
00650 fprintf(stdout,"StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
00651 " %s, bufpos=%d, arr=%p, eoffset=%d, Redirect=%p\n",
00652 info->GetClass()->GetName(),aElement->GetName(),fElemId,info->GetTypes()[fElemId],
00653 aElement->ClassName(),b.Length(),addr, 0,b.PeekDataCache()->GetObjectAt(0));
00654 }
00655
00656 }
00657 virtual ~TConfigurationUseCache() {};
00658 virtual TConfiguration *Copy() {
00659 TConfigurationUseCache *copy = new TConfigurationUseCache(*this);
00660 fAction.fConfiguration = copy->fAction.fConfiguration->Copy();
00661 return copy;
00662 }
00663 };
00664
00665
00666 inline Int_t UseCache(TBuffer &b, void *addr, const TConfiguration *conf)
00667 {
00668 TConfigurationUseCache *config = (TConfigurationUseCache*)conf;
00669
00670 Int_t bufpos = b.Length();
00671 TVirtualArray *cached = b.PeekDataCache();
00672 if (cached==0) {
00673 TStreamerElement *aElement = (TStreamerElement*)conf->fInfo->GetElems()[conf->fElemId];
00674 TStreamerInfo *info = (TStreamerInfo*)conf->fInfo;
00675 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
00676 char *ptr = (char*)addr;
00677 info->ReadBufferSkip(b,&ptr,config->fElemId,info->GetTypes()[config->fElemId]+TStreamerInfo::kSkip,aElement,1,0);
00678 } else {
00679 config->fAction(b, (*cached)[0]);
00680 }
00681
00682 if (config->fNeedRepeat) {
00683 b.SetBufferOffset(bufpos);
00684 }
00685 return 0;
00686 }
00687
00688 inline Int_t UseCacheVectorPtrLoop(TBuffer &b, void *start, const void *end, const TConfiguration *conf)
00689 {
00690 TConfigurationUseCache *config = (TConfigurationUseCache*)conf;
00691 Int_t bufpos = b.Length();
00692
00693 TVirtualArray *cached = b.PeekDataCache();
00694 if (cached==0) {
00695 TStreamerElement *aElement = (TStreamerElement*)config->fInfo->GetElems()[config->fElemId];
00696 TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
00697 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
00698 char *ptr = (char*)start;
00699 UInt_t n = (((void**)end)-((void**)start));
00700 info->ReadBufferSkip(b,&ptr,config->fElemId,info->GetTypes()[config->fElemId]+TStreamerInfo::kSkip,aElement,n,0);
00701 } else {
00702 TVectorLoopConfig cached_config( cached->fClass->Size() );
00703 void *cached_start = (*cached)[0];
00704 void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
00705 config->fAction(b,cached_start,cached_end,&cached_config);
00706 }
00707
00708 if (config->fNeedRepeat) {
00709 b.SetBufferOffset(bufpos);
00710 }
00711 return 0;
00712 }
00713
00714 inline Int_t UseCacheVectorLoop(TBuffer &b, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *conf)
00715 {
00716 TConfigurationUseCache *config = (TConfigurationUseCache*)conf;
00717
00718 Int_t bufpos = b.Length();
00719 TVirtualArray *cached = b.PeekDataCache();
00720 if (cached==0) {
00721 TStreamerElement *aElement = (TStreamerElement*)config->fInfo->GetElems()[config->fElemId];
00722 TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
00723 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
00724 char *ptr = (char*)start;
00725 UInt_t n = (((char*)end)-((char*)start))/((TVectorLoopConfig*)loopconf)->fIncrement;
00726 info->ReadBufferSkip(b,&ptr,config->fElemId,info->GetTypes()[config->fElemId]+TStreamerInfo::kSkip,aElement,n,0);
00727 } else {
00728 TVectorLoopConfig cached_config( cached->fClass->Size() );
00729 void *cached_start = (*cached)[0];
00730 void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
00731 config->fAction(b,cached_start,cached_end,&cached_config);
00732 }
00733
00734 if (config->fNeedRepeat) {
00735 b.SetBufferOffset(bufpos);
00736 }
00737 return 0;
00738 }
00739
00740 inline Int_t UseCacheGenericCollection(TBuffer &b, void *, const void *, const TLoopConfiguration *loopconfig, const TConfiguration *conf)
00741 {
00742 TConfigurationUseCache *config = (TConfigurationUseCache*)conf;
00743
00744 Int_t bufpos = b.Length();
00745 TVirtualArray *cached = b.PeekDataCache();
00746 if (cached==0) {
00747 TStreamerElement *aElement = (TStreamerElement*)config->fInfo->GetElems()[config->fElemId];
00748 TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
00749
00750 TVirtualCollectionProxy *proxy = ((TGenericLoopConfig*)loopconfig)->fProxy;
00751 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
00752 UInt_t n = proxy->Size();
00753 info->ReadBufferSkip(b, *proxy,config->fElemId,info->GetTypes()[config->fElemId]+TStreamerInfo::kSkip,aElement,n,0);
00754 } else {
00755 TVectorLoopConfig cached_config( cached->fClass->Size() );
00756 void *cached_start = (*cached)[0];
00757 void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
00758 config->fAction(b,cached_start,cached_end,&cached_config);
00759 }
00760
00761 if (config->fNeedRepeat) {
00762 b.SetBufferOffset(bufpos);
00763 }
00764 return 0;
00765 }
00766
00767
00768
00769 Int_t GenericVectorPtrAction(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
00770 {
00771 Int_t n = ( ((void**)end) - ((void**)iter) );
00772 char **arr = (char**)iter;
00773 return ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arr, config->fElemId, n, config->fOffset, 1|2 );
00774 }
00775
00776 Int_t ReadVectorBase(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
00777 {
00778
00779
00780
00781 UInt_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
00782 UInt_t n = (((char*)end)-((char*)start))/incr;
00783 char **arrptr = new char*[n];
00784 UInt_t i = 0;
00785 for(void *iter = start; iter != end; iter = (char*)iter + incr, ++i ) {
00786 arrptr[i] = (char*)iter;
00787 }
00788 ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arrptr, config->fElemId, n, config->fOffset, 1|2 );
00789 delete [] arrptr;
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808 return 0;
00809 }
00810
00811 Int_t ReadVectorWrapping(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
00812 {
00813
00814
00815 UInt_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
00816 UInt_t n = (((char*)end)-((char*)start))/incr;
00817 char **arrptr = new char*[n];
00818 UInt_t i = 0;
00819 for(void *iter = start; iter != end; iter = (char*)iter + incr, ++i ) {
00820 arrptr[i] = (char*)iter;
00821 }
00822 ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arrptr, config->fElemId, n, config->fOffset, 1|2 );
00823 delete [] arrptr;
00824 return 0;
00825 }
00826
00827 Int_t GenericVectorAction(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
00828 {
00829 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
00830 for(void *iter = start; iter != end; iter = (char*)iter + incr ) {
00831 void **iter_ptr = &iter;
00832 ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, (char**)iter_ptr, config->fElemId, 1, config->fOffset, 1|2 );
00833 }
00834 return 0;
00835 }
00836
00837 Int_t GenericCollectionAction(TBuffer &buf, void *, const void *, const TLoopConfiguration * loopconf, const TConfiguration *config)
00838 {
00839 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
00840 TVirtualCollectionProxy *proxy = loopconfig->fProxy;
00841 return ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, *proxy, config->fElemId, proxy->Size(), config->fOffset, 1|2 );
00842 }
00843
00844 Int_t GenericAssocCollectionAction(TBuffer &buf, void *, const void *, const TLoopConfiguration *loopconf, const TConfiguration *config)
00845 {
00846 TAssocLoopConfig *loopconfig = (TAssocLoopConfig*)loopconf;
00847 TVirtualCollectionProxy *proxy = loopconfig->fProxy;
00848 return ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, *proxy, config->fElemId, proxy->Size(), config->fOffset, 1|2 );
00849 }
00850
00851 template <typename T>
00852 Int_t ReadBasicTypeVectorLoop(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
00853 {
00854 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
00855 iter = (char*)iter + config->fOffset;
00856 end = (char*)end + config->fOffset;
00857 for(; iter != end; iter = (char*)iter + incr ) {
00858 T *x = (T*) ((char*) iter);
00859 buf >> *x;
00860 }
00861 return 0;
00862 }
00863
00864 template <typename T>
00865 Int_t ReadBasicTypeGenericLoop(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
00866 {
00867 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
00868
00869
00870 Next_t next = loopconfig->fNext;
00871 const Int_t offset = config->fOffset;
00872
00873 char iterator[TVirtualCollectionProxy::fgIteratorArenaSize];
00874 void *iter = loopconfig->fCopyIterator(iterator,start);
00875 void *addr;
00876 while( (addr = next(iter,end)) ) {
00877 T *x = (T*)( ((char*)addr) + offset );
00878 buf >> *x;
00879 }
00880 if (iter != &iterator[0]) {
00881 loopconfig->fDeleteIterator(iter);
00882 }
00883 return 0;
00884 }
00885
00886 template <typename T>
00887 Int_t ReadBasicTypeVectorPtrLoop(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
00888 {
00889 const Int_t offset = config->fOffset;
00890
00891 for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
00892 T *x = (T*)( ((char*) (*(void**)iter) ) + offset );
00893 buf >> *x;
00894 }
00895 return 0;
00896 }
00897
00898 template <Int_t (*action)(TBuffer&,void *,const TConfiguration*)>
00899 Int_t VectorPtrLooper(TBuffer &buf, void *start, const void *end, const TConfiguration *config)
00900 {
00901 for(void *iter = start; iter != end; iter = (char*)iter + sizeof(void*) ) {
00902 action(buf, *(void**)iter, config);
00903 }
00904 return 0;
00905 }
00906
00907 template <Int_t (*action)(TBuffer&,void *,const TConfiguration*)>
00908 Int_t VectorLooper(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
00909 {
00910 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
00911
00912
00913 for(void *iter = start; iter != end; iter = (char*)iter + incr ) {
00914 action(buf, iter, config);
00915 }
00916 return 0;
00917 }
00918
00919 template <Int_t (*action)(TBuffer&,void *,const TConfiguration*)>
00920 Int_t GenericLooper(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
00921 {
00922 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
00923
00924
00925 Next_t next = loopconfig->fNext;
00926
00927 char iterator[TVirtualCollectionProxy::fgIteratorArenaSize];
00928 void *iter = loopconfig->fCopyIterator(&iterator,start);
00929 void *addr;
00930 while( (addr = next(iter,end)) ) {
00931 action(buf, addr, config);
00932 }
00933 if (iter != &iterator[0]) {
00934 loopconfig->fDeleteIterator(iter);
00935 }
00936 return 0;
00937 }
00938
00939 }
00940
00941 static TConfiguredAction GetVectorAction(TVirtualStreamerInfo *info, TStreamerElement *element, Int_t type, UInt_t i, Int_t offset)
00942 {
00943 switch (type) {
00944
00945 case TStreamerInfo::kBool: return TConfiguredAction( ReadBasicTypeVectorLoop<Bool_t>, new TConfiguration(info,i,offset) ); break;
00946 case TStreamerInfo::kChar: return TConfiguredAction( ReadBasicTypeVectorLoop<Char_t>, new TConfiguration(info,i,offset) ); break;
00947 case TStreamerInfo::kShort: return TConfiguredAction( ReadBasicTypeVectorLoop<Short_t>, new TConfiguration(info,i,offset) ); break;
00948 case TStreamerInfo::kInt: return TConfiguredAction( ReadBasicTypeVectorLoop<Int_t>, new TConfiguration(info,i,offset) ); break;
00949 case TStreamerInfo::kLong: return TConfiguredAction( ReadBasicTypeVectorLoop<Long_t>, new TConfiguration(info,i,offset) ); break;
00950 case TStreamerInfo::kLong64: return TConfiguredAction( ReadBasicTypeVectorLoop<Long64_t>, new TConfiguration(info,i,offset) ); break;
00951 case TStreamerInfo::kFloat: return TConfiguredAction( ReadBasicTypeVectorLoop<Float_t>, new TConfiguration(info,i,offset) ); break;
00952 case TStreamerInfo::kDouble: return TConfiguredAction( ReadBasicTypeVectorLoop<Double_t>, new TConfiguration(info,i,offset) ); break;
00953 case TStreamerInfo::kUChar: return TConfiguredAction( ReadBasicTypeVectorLoop<UChar_t>, new TConfiguration(info,i,offset) ); break;
00954 case TStreamerInfo::kUShort: return TConfiguredAction( ReadBasicTypeVectorLoop<UShort_t>, new TConfiguration(info,i,offset) ); break;
00955 case TStreamerInfo::kUInt: return TConfiguredAction( ReadBasicTypeVectorLoop<UInt_t>, new TConfiguration(info,i,offset) ); break;
00956 case TStreamerInfo::kULong: return TConfiguredAction( ReadBasicTypeVectorLoop<ULong_t>, new TConfiguration(info,i,offset) ); break;
00957 case TStreamerInfo::kULong64: return TConfiguredAction( ReadBasicTypeVectorLoop<ULong64_t>, new TConfiguration(info,i,offset) ); break;
00958 case TStreamerInfo::kFloat16: {
00959 if (element->GetFactor() != 0) {
00960 return TConfiguredAction( VectorLooper<ReadBasicType_WithFactor<float> >, new TConfWithFactor(info,i,offset,element->GetFactor(),element->GetXmin()) );
00961 } else {
00962 Int_t nbits = (Int_t)element->GetXmin();
00963 if (!nbits) nbits = 12;
00964 return TConfiguredAction( VectorLooper<ReadBasicType_NoFactor<float> >, new TConfNoFactor(info,i,offset,nbits) );
00965 }
00966 break;
00967 }
00968 case TStreamerInfo::kDouble32: {
00969 if (element->GetFactor() != 0) {
00970 return TConfiguredAction( VectorLooper<ReadBasicType_WithFactor<double> >, new TConfWithFactor(info,i,offset,element->GetFactor(),element->GetXmin()) );
00971 } else {
00972 Int_t nbits = (Int_t)element->GetXmin();
00973 if (!nbits) {
00974 return TConfiguredAction( VectorLooper<ConvertBasicType<float,double> >, new TConfiguration(info,i,offset) );
00975 } else {
00976 return TConfiguredAction( VectorLooper<ReadBasicType_NoFactor<double> >, new TConfNoFactor(info,i,offset,nbits) );
00977 }
00978 }
00979 break;
00980 }
00981 case TStreamerInfo::kTNamed: return TConfiguredAction( VectorLooper<ReadTNamed >, new TConfiguration(info,i,offset) ); break;
00982
00983
00984 case TStreamerInfo::kTObject: return TConfiguredAction( VectorLooper<ReadTObject >, new TConfiguration(info,i,offset) ); break;
00985 case TStreamerInfo::kTString: return TConfiguredAction( VectorLooper<ReadTString >, new TConfiguration(info,i,offset) ); break;
00986 case TStreamerInfo::kArtificial:
00987 case TStreamerInfo::kCacheNew:
00988 case TStreamerInfo::kCacheDelete:
00989 case TStreamerInfo::kSTL: return TConfiguredAction( ReadVectorWrapping, new TConfiguration(info,i,0 ) ); break;
00990 case TStreamerInfo::kBase: return TConfiguredAction( ReadVectorBase, new TConfiguration(info,i,0 ) ); break;
00991 default:
00992 return TConfiguredAction( ReadVectorWrapping, new TConfiguration(info,i,0 ) );
00993
00994 break;
00995 }
00996 R__ASSERT(0);
00997 return TConfiguredAction();
00998 }
00999
01000
01001 void TStreamerInfo::Compile()
01002 {
01003
01004
01005
01006
01007
01008 R__LOCKGUARD(gCINTMutex);
01009
01010
01011
01012
01013
01014 fOptimized = kFALSE;
01015 fNdata = 0;
01016
01017 TObjArray* infos = (TObjArray*) gROOT->GetListOfStreamerInfo();
01018 if (fNumber >= infos->GetSize()) {
01019 infos->AddAtAndExpand(this, fNumber);
01020 } else {
01021 if (!infos->At(fNumber)) {
01022 infos->AddAt(this, fNumber);
01023 }
01024 }
01025
01026 delete[] fType;
01027 fType = 0;
01028 delete[] fNewType;
01029 fNewType = 0;
01030 delete[] fOffset;
01031 fOffset = 0;
01032 delete[] fLength;
01033 fLength = 0;
01034 delete[] fElem;
01035 fElem = 0;
01036 delete[] fMethod;
01037 fMethod = 0;
01038 delete[] fComp;
01039 fComp = 0;
01040
01041 if (fReadObjectWise) {
01042 fReadObjectWise->fActions.clear();
01043 }
01044 Int_t ndata = fElements->GetEntries();
01045
01046 fOffset = new Int_t[ndata+1];
01047 fType = new Int_t[ndata+1];
01048
01049 SetBit(kIsCompiled);
01050 if (!fReadObjectWise) fReadObjectWise = new TStreamerInfoActions::TActionSequence(this,ndata);
01051
01052 if (!ndata) {
01053
01054
01055 if (fClass->TestBit(TClass::kIsEmulation) && fNVirtualInfoLoc!=0) {
01056 fSize = sizeof(TStreamerInfo*);
01057 }
01058 return;
01059 }
01060
01061
01062 fComp = new TCompInfo[ndata];
01063 fNewType = new Int_t[ndata];
01064 fLength = new Int_t[ndata];
01065 fElem = new ULong_t[ndata];
01066 fMethod = new ULong_t[ndata];
01067
01068 TStreamerElement* element;
01069 TStreamerElement* previous = 0;
01070 Int_t keep = -1;
01071 Int_t i;
01072
01073 if (!CanOptimize()) {
01074 SetBit(kCannotOptimize);
01075 }
01076
01077 Bool_t isOptimized = kFALSE;
01078
01079 for (i = 0; i < ndata; ++i) {
01080 element = (TStreamerElement*) fElements->At(i);
01081 if (!element) {
01082 break;
01083 }
01084 if (element->GetType() < 0) {
01085
01086
01087
01088
01089
01090
01091
01092
01093 continue;
01094 }
01095 if (TestBit(kCannotOptimize) && element->IsBase())
01096 {
01097
01098
01099 TClass *bclass = element->GetClassPointer();
01100 Int_t clversion = ((TStreamerBase*)element)->GetBaseVersion();
01101 TStreamerInfo *binfo = ((TStreamerInfo*)bclass->GetStreamerInfo(clversion));
01102 binfo->SetBit(kCannotOptimize);
01103 if (binfo->IsOptimized())
01104 {
01105
01106 binfo->Compile();
01107 }
01108 }
01109 Int_t asize = element->GetSize();
01110 if (element->GetArrayLength()) {
01111 asize /= element->GetArrayLength();
01112 }
01113 fType[fNdata] = element->GetType();
01114 fNewType[fNdata] = element->GetNewType();
01115 fOffset[fNdata] = element->GetOffset();
01116 fLength[fNdata] = element->GetArrayLength();
01117 fElem[fNdata] = (ULong_t) element;
01118 fMethod[fNdata] = element->GetMethod();
01119
01120 if (!TestBit(kCannotOptimize)
01121 && (keep >= 0)
01122 && (element->GetType() < 10)
01123 && (fType[fNdata] == fNewType[fNdata])
01124 && (fMethod[keep] == 0)
01125 && (element->GetType() > 0)
01126 && (element->GetArrayDim() == 0)
01127 && (fType[keep] < kObject)
01128 && (fType[keep] != kCharStar)
01129 && (element->GetType() == (fType[keep]%kRegrouped))
01130 && ((element->GetOffset()-fOffset[keep]) == (fLength[keep])*asize)
01131 && ((fOldVersion<6) || !previous ||
01132 ((element->GetFactor() == previous->GetFactor())
01133 && (element->GetXmin() == previous->GetXmin())
01134 && (element->GetXmax() == previous->GetXmax())
01135 )
01136 )
01137 && (element->TestBit(TStreamerElement::kCache) == previous->TestBit(TStreamerElement::kCache))
01138 )
01139 {
01140 if (fLength[keep] == 0) {
01141 fLength[keep]++;
01142 }
01143 fLength[keep]++;
01144 fType[keep] = element->GetType() + kRegrouped;
01145 isOptimized = kTRUE;
01146 } else {
01147 if (fNewType[fNdata] != fType[fNdata]) {
01148 if (fNewType[fNdata] > 0) {
01149 if (fType[fNdata] != kCounter) {
01150 fType[fNdata] += kConv;
01151 }
01152 } else {
01153 if (fType[fNdata] == kCounter) {
01154 Warning("Compile", "Counter %s should not be skipped from class %s", element->GetName(), GetName());
01155 }
01156 fType[fNdata] += kSkip;
01157 }
01158 }
01159 keep = fNdata;
01160 if (fLength[keep] == 0) {
01161 fLength[keep] = 1;
01162 }
01163 fNdata++;
01164 }
01165 previous = element;
01166 }
01167
01168 if ( ! isOptimized ) {
01169 if (fReadMemberWise) fReadMemberWise->fActions.clear();
01170 else fReadMemberWise = new TStreamerInfoActions::TActionSequence(this,ndata);
01171 }
01172
01173 for (i = 0; i < fNdata; ++i) {
01174 element = (TStreamerElement*) fElem[i];
01175 if (!element) {
01176 continue;
01177 }
01178 fComp[i].fClass = element->GetClassPointer();
01179 fComp[i].fNewClass = element->GetNewClass();
01180 fComp[i].fClassName = TString(element->GetTypeName()).Strip(TString::kTrailing, '*');
01181 fComp[i].fStreamer = element->GetStreamer();
01182
01183 switch (fType[i]) {
01184
01185 case TStreamerInfo::kBool: fReadObjectWise->AddAction( ReadBasicType<Bool_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01186 case TStreamerInfo::kChar: fReadObjectWise->AddAction( ReadBasicType<Char_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01187 case TStreamerInfo::kShort: fReadObjectWise->AddAction( ReadBasicType<Short_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01188 case TStreamerInfo::kInt: fReadObjectWise->AddAction( ReadBasicType<Int_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01189 case TStreamerInfo::kLong: fReadObjectWise->AddAction( ReadBasicType<Long_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01190 case TStreamerInfo::kLong64: fReadObjectWise->AddAction( ReadBasicType<Long64_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01191 case TStreamerInfo::kFloat: fReadObjectWise->AddAction( ReadBasicType<Float_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01192 case TStreamerInfo::kDouble: fReadObjectWise->AddAction( ReadBasicType<Double_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01193 case TStreamerInfo::kUChar: fReadObjectWise->AddAction( ReadBasicType<UChar_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01194 case TStreamerInfo::kUShort: fReadObjectWise->AddAction( ReadBasicType<UShort_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01195 case TStreamerInfo::kUInt: fReadObjectWise->AddAction( ReadBasicType<UInt_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01196 case TStreamerInfo::kULong: fReadObjectWise->AddAction( ReadBasicType<ULong_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01197 case TStreamerInfo::kULong64: fReadObjectWise->AddAction( ReadBasicType<ULong64_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01198 case TStreamerInfo::kFloat16: {
01199 if (element->GetFactor() != 0) {
01200 fReadObjectWise->AddAction( ReadBasicType_WithFactor<float>, new TConfWithFactor(this,i,fOffset[i],element->GetFactor(),element->GetXmin()) );
01201 } else {
01202 Int_t nbits = (Int_t)element->GetXmin();
01203 if (!nbits) nbits = 12;
01204 fReadObjectWise->AddAction( ReadBasicType_NoFactor<float>, new TConfNoFactor(this,i,fOffset[i],nbits) );
01205 }
01206 break;
01207 }
01208 case TStreamerInfo::kDouble32: {
01209 if (element->GetFactor() != 0) {
01210 fReadObjectWise->AddAction( ReadBasicType_WithFactor<double>, new TConfWithFactor(this,i,fOffset[i],element->GetFactor(),element->GetXmin()) );
01211 } else {
01212 Int_t nbits = (Int_t)element->GetXmin();
01213 if (!nbits) {
01214 fReadObjectWise->AddAction( ConvertBasicType<float,double>, new TConfiguration(this,i,fOffset[i]) );
01215 } else {
01216 fReadObjectWise->AddAction( ReadBasicType_NoFactor<double>, new TConfNoFactor(this,i,fOffset[i],nbits) );
01217 }
01218 }
01219 break;
01220 }
01221 case TStreamerInfo::kTNamed: fReadObjectWise->AddAction( ReadTNamed, new TConfiguration(this,i,fOffset[i]) ); break;
01222
01223
01224 case TStreamerInfo::kTObject: fReadObjectWise->AddAction( ReadTObject, new TConfiguration(this,i,fOffset[i]) ); break;
01225 case TStreamerInfo::kTString: fReadObjectWise->AddAction( ReadTString, new TConfiguration(this,i,fOffset[i]) ); break;
01226 case TStreamerInfo::kSTL: {
01227 TClass *newClass = element->GetNewClass();
01228 TClass *oldClass = element->GetClassPointer();
01229 Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();
01230
01231 if (element->GetArrayLength() <= 1) {
01232 if (fOldVersion<3){
01233 if (newClass && newClass != oldClass) {
01234 if (element->GetStreamer()) {
01235 fReadObjectWise->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,fOffset[i],1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
01236 } else {
01237 fReadObjectWise->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,fOffset[i],1,oldClass,newClass,element->GetTypeName(),isSTLbase));
01238 }
01239 } else {
01240 if (element->GetStreamer()) {
01241 fReadObjectWise->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,fOffset[i],1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
01242 } else {
01243 fReadObjectWise->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,fOffset[i],1,oldClass,element->GetTypeName(),isSTLbase));
01244 }
01245 }
01246 } else {
01247 if (newClass && newClass != oldClass) {
01248 if (element->GetStreamer()) {
01249 fReadObjectWise->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,fOffset[i],1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
01250 } else {
01251 fReadObjectWise->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,fOffset[i],1,oldClass,newClass,element->GetTypeName(),isSTLbase));
01252 }
01253 } else {
01254 if (element->GetStreamer()) {
01255 fReadObjectWise->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,fOffset[i],1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
01256 } else {
01257 fReadObjectWise->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,fOffset[i],1,oldClass,element->GetTypeName(),isSTLbase));
01258 }
01259 }
01260 }
01261 } else {
01262 if (fOldVersion<3){
01263 if (newClass && newClass != oldClass) {
01264 if (element->GetStreamer()) {
01265 fReadObjectWise->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,fOffset[i],element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
01266 } else {
01267 fReadObjectWise->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,fOffset[i],element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
01268 }
01269 } else {
01270 if (element->GetStreamer()) {
01271 fReadObjectWise->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,fOffset[i],element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
01272 } else {
01273 fReadObjectWise->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,fOffset[i],element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
01274 }
01275 }
01276 } else {
01277 if (newClass && newClass != oldClass) {
01278 if (element->GetStreamer()) {
01279 fReadObjectWise->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,fOffset[i],element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
01280 } else {
01281 fReadObjectWise->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,fOffset[i],element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
01282 }
01283 } else {
01284 if (element->GetStreamer()) {
01285 fReadObjectWise->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,fOffset[i],element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
01286 } else {
01287 fReadObjectWise->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,fOffset[i],element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
01288 }
01289 }
01290 }
01291 }
01292 break;
01293 }
01294 default:
01295 fReadObjectWise->AddAction( GenericAction, new TGenericConfiguration(this,i) );
01296 break;
01297 }
01298 if (element->TestBit(TStreamerElement::kCache)) {
01299 TConfiguredAction action( fReadObjectWise->fActions.back() );
01300 fReadObjectWise->fActions.pop_back();
01301 fReadObjectWise->AddAction( UseCache, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
01302 }
01303 if (fReadMemberWise) {
01304
01305
01306 if (element->TestBit(TStreamerElement::kCache)) {
01307 TConfiguredAction action( GetVectorAction(this,element,fType[i],i,fOffset[i]) );
01308 fReadMemberWise->AddAction( UseCacheVectorPtrLoop, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
01309 } else {
01310 switch (fType[i]) {
01311
01312 case TStreamerInfo::kBool: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<Bool_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01313 case TStreamerInfo::kChar: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<Char_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01314 case TStreamerInfo::kShort: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<Short_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01315 case TStreamerInfo::kInt: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<Int_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01316 case TStreamerInfo::kLong: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<Long_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01317 case TStreamerInfo::kLong64: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<Long64_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01318 case TStreamerInfo::kFloat: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<Float_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01319 case TStreamerInfo::kDouble: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<Double_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01320 case TStreamerInfo::kUChar: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<UChar_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01321 case TStreamerInfo::kUShort: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<UShort_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01322 case TStreamerInfo::kUInt: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<UInt_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01323 case TStreamerInfo::kULong: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<ULong_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01324 case TStreamerInfo::kULong64: fReadMemberWise->AddAction( ReadBasicTypeVectorPtrLoop<ULong64_t>, new TConfiguration(this,i,fOffset[i]) ); break;
01325 case TStreamerInfo::kFloat16: {
01326 if (element->GetFactor() != 0) {
01327 fReadMemberWise->AddAction( VectorPtrLooper<ReadBasicType_WithFactor<float> >, new TConfWithFactor(this,i,fOffset[i],element->GetFactor(),element->GetXmin()) );
01328 } else {
01329 Int_t nbits = (Int_t)element->GetXmin();
01330 if (!nbits) nbits = 12;
01331 fReadMemberWise->AddAction( VectorPtrLooper<ReadBasicType_NoFactor<float> >, new TConfNoFactor(this,i,fOffset[i],nbits) );
01332 }
01333 break;
01334 }
01335 case TStreamerInfo::kDouble32: {
01336 if (element->GetFactor() != 0) {
01337 fReadMemberWise->AddAction( VectorPtrLooper<ReadBasicType_WithFactor<double> >, new TConfWithFactor(this,i,fOffset[i],element->GetFactor(),element->GetXmin()) );
01338 } else {
01339 Int_t nbits = (Int_t)element->GetXmin();
01340 if (!nbits) {
01341 fReadMemberWise->AddAction( VectorPtrLooper<ConvertBasicType<float,double> >, new TConfiguration(this,i,fOffset[i]) );
01342 } else {
01343 fReadMemberWise->AddAction( VectorPtrLooper<ReadBasicType_NoFactor<double> >, new TConfNoFactor(this,i,fOffset[i],nbits) );
01344 }
01345 }
01346 break;
01347 }
01348 case TStreamerInfo::kTNamed: fReadMemberWise->AddAction( VectorPtrLooper<ReadTNamed >, new TConfiguration(this,i,fOffset[i]) ); break;
01349
01350
01351 case TStreamerInfo::kTObject: fReadMemberWise->AddAction( VectorPtrLooper<ReadTObject >, new TConfiguration(this,i,fOffset[i]) ); break;
01352 case TStreamerInfo::kTString: fReadMemberWise->AddAction( VectorPtrLooper<ReadTString >, new TConfiguration(this,i,fOffset[i]) ); break;
01353 default:
01354 fReadMemberWise->AddAction( GenericVectorPtrAction, new TGenericConfiguration(this,i) );
01355 break;
01356 }
01357 }
01358 }
01359 }
01360 ComputeSize();
01361
01362 fOptimized = isOptimized;
01363
01364 if (gDebug > 0) {
01365 ls();
01366 }
01367 }
01368
01369 TStreamerInfoActions::TActionSequence *TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy)
01370 {
01371
01372
01373 if (info == 0) {
01374 return new TStreamerInfoActions::TActionSequence(0,0);
01375 }
01376
01377 if (info->IsOptimized()) {
01378
01379 info->SetBit(TVirtualStreamerInfo::kCannotOptimize);
01380 info->Compile();
01381 }
01382 UInt_t ndata = info->GetElements()->GetEntries();
01383 TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(info,ndata);
01384 if ( (proxy.GetCollectionType() == TClassEdit::kVector) || (proxy.GetProperties() & TVirtualCollectionProxy::kIsEmulated) )
01385 {
01386 if (proxy.HasPointers()) {
01387
01388 delete sequence;
01389
01390 sequence = static_cast<TStreamerInfo*>(info)->GetReadMemberWiseActions(kTRUE)->CreateCopy();
01391
01392 return sequence;
01393 }
01394
01395
01396 Long_t increment = proxy.GetIncrement();
01397 sequence->fLoopConfig = new TVectorLoopConfig(increment);
01398 } else if (proxy.GetCollectionType() == TClassEdit::kSet || proxy.GetCollectionType() == TClassEdit::kMultiSet
01399 || proxy.GetCollectionType() == TClassEdit::kMap || proxy.GetCollectionType() == TClassEdit::kMultiMap)
01400 {
01401 Long_t increment = proxy.GetIncrement();
01402 sequence->fLoopConfig = new TVectorLoopConfig(increment);
01403
01404 } else {
01405 sequence->fLoopConfig = new TGenericLoopConfig(&proxy);
01406 }
01407 for (UInt_t i = 0; i < ndata; ++i) {
01408 TStreamerElement *element = (TStreamerElement*) info->GetElements()->At(i);
01409 if (!element) {
01410 break;
01411 }
01412 if (element->GetType() < 0) {
01413
01414
01415
01416
01417
01418 continue;
01419 }
01420 Int_t asize = element->GetSize();
01421 if (element->GetArrayLength()) {
01422 asize /= element->GetArrayLength();
01423 }
01424 Int_t oldType = element->GetType();
01425 Int_t newType = element->GetNewType();
01426
01427 Int_t offset = element->GetOffset();
01428 if (newType != oldType) {
01429 if (newType > 0) {
01430 if (oldType != TVirtualStreamerInfo::kCounter) {
01431 oldType += TVirtualStreamerInfo::kConv;
01432 }
01433 } else {
01434 oldType += TVirtualStreamerInfo::kSkip;
01435 }
01436 }
01437 if ( (proxy.GetCollectionType() == TClassEdit::kVector) || (proxy.GetProperties() & TVirtualCollectionProxy::kIsEmulated)
01438 || (proxy.GetCollectionType() == TClassEdit::kSet || proxy.GetCollectionType() == TClassEdit::kMultiSet
01439 || proxy.GetCollectionType() == TClassEdit::kMap || proxy.GetCollectionType() == TClassEdit::kMultiMap) )
01440 {
01441
01442
01443 if (element->TestBit(TStreamerElement::kCache)) {
01444 TConfiguredAction action( GetVectorAction(info,element,oldType,i,offset) );
01445 sequence->AddAction( UseCacheVectorLoop, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
01446 } else {
01447 sequence->AddAction(GetVectorAction(info,element,oldType,i,offset));
01448 }
01449
01450
01451
01452
01453 } else {
01454
01455 if (element->TestBit(TStreamerElement::kCache)) {
01456 TConfiguredAction action( GetVectorAction(info,element,oldType,i,offset) );
01457 sequence->AddAction( UseCacheGenericCollection, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
01458 } else {
01459 switch (oldType) {
01460
01461 case TStreamerInfo::kBool: sequence->AddAction( ReadBasicTypeGenericLoop<Bool_t>, new TConfiguration(info,i,offset) ); break;
01462 case TStreamerInfo::kChar: sequence->AddAction( ReadBasicTypeGenericLoop<Char_t>, new TConfiguration(info,i,offset) ); break;
01463 case TStreamerInfo::kShort: sequence->AddAction( ReadBasicTypeGenericLoop<Short_t>, new TConfiguration(info,i,offset) ); break;
01464 case TStreamerInfo::kInt: sequence->AddAction( ReadBasicTypeGenericLoop<Int_t>, new TConfiguration(info,i,offset) ); break;
01465 case TStreamerInfo::kLong: sequence->AddAction( ReadBasicTypeGenericLoop<Long_t>, new TConfiguration(info,i,offset) ); break;
01466 case TStreamerInfo::kLong64: sequence->AddAction( ReadBasicTypeGenericLoop<Long64_t>, new TConfiguration(info,i,offset) ); break;
01467 case TStreamerInfo::kFloat: sequence->AddAction( ReadBasicTypeGenericLoop<Float_t>, new TConfiguration(info,i,offset) ); break;
01468 case TStreamerInfo::kDouble: sequence->AddAction( ReadBasicTypeGenericLoop<Double_t>, new TConfiguration(info,i,offset) ); break;
01469 case TStreamerInfo::kUChar: sequence->AddAction( ReadBasicTypeGenericLoop<UChar_t>, new TConfiguration(info,i,offset) ); break;
01470 case TStreamerInfo::kUShort: sequence->AddAction( ReadBasicTypeGenericLoop<UShort_t>, new TConfiguration(info,i,offset) ); break;
01471 case TStreamerInfo::kUInt: sequence->AddAction( ReadBasicTypeGenericLoop<UInt_t>, new TConfiguration(info,i,offset) ); break;
01472 case TStreamerInfo::kULong: sequence->AddAction( ReadBasicTypeGenericLoop<ULong_t>, new TConfiguration(info,i,offset) ); break;
01473 case TStreamerInfo::kULong64: sequence->AddAction( ReadBasicTypeGenericLoop<ULong64_t>, new TConfiguration(info,i,offset) ); break;
01474 case TStreamerInfo::kFloat16: {
01475 if (element->GetFactor() != 0) {
01476 sequence->AddAction( GenericLooper<ReadBasicType_WithFactor<float> >, new TConfWithFactor(info,i,offset,element->GetFactor(),element->GetXmin()) );
01477 } else {
01478 Int_t nbits = (Int_t)element->GetXmin();
01479 if (!nbits) nbits = 12;
01480 sequence->AddAction( GenericLooper<ReadBasicType_NoFactor<float> >, new TConfNoFactor(info,i,offset,nbits) );
01481 }
01482 break;
01483 }
01484 case TStreamerInfo::kDouble32: {
01485 if (element->GetFactor() != 0) {
01486 sequence->AddAction( GenericLooper<ReadBasicType_WithFactor<double> >, new TConfWithFactor(info,i,offset,element->GetFactor(),element->GetXmin()) );
01487 } else {
01488 Int_t nbits = (Int_t)element->GetXmin();
01489 if (!nbits) {
01490 sequence->AddAction( GenericLooper<ConvertBasicType<float,double> >, new TConfiguration(info,i,offset) );
01491 } else {
01492 sequence->AddAction( GenericLooper<ReadBasicType_NoFactor<double> >, new TConfNoFactor(info,i,offset,nbits) );
01493 }
01494 }
01495 break;
01496 }
01497 case TStreamerInfo::kTNamed: sequence->AddAction( GenericLooper<ReadTNamed >, new TConfiguration(info,i,offset) ); break;
01498
01499
01500 case TStreamerInfo::kTObject: sequence->AddAction( GenericLooper<ReadTObject >, new TConfiguration(info,i,offset) ); break;
01501 case TStreamerInfo::kTString: sequence->AddAction( GenericLooper<ReadTString >, new TConfiguration(info,i,offset) ); break;
01502 default:
01503 sequence->AddAction( GenericCollectionAction, new TConfigSTL(info,i,0 ,0,proxy.GetCollectionClass(),0,0) );
01504 break;
01505 }
01506 }
01507 }
01508 }
01509 return sequence;
01510 }
01511
01512 void TStreamerInfoActions::TActionSequence::AddToOffset(Int_t delta)
01513 {
01514
01515
01516
01517 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
01518 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
01519 iter != end;
01520 ++iter)
01521 {
01522 iter->fConfiguration->AddToOffset(delta);
01523 }
01524 }
01525
01526 TStreamerInfoActions::TActionSequence *TStreamerInfoActions::TActionSequence::CreateCopy()
01527 {
01528
01529
01530 TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo,fActions.size());
01531
01532 sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
01533
01534 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
01535 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
01536 iter != end;
01537 ++iter)
01538 {
01539 TConfiguration *conf = iter->fConfiguration->Copy();
01540 sequence->AddAction( iter->fAction, conf );
01541 }
01542 return sequence;
01543 }
01544
01545 TStreamerInfoActions::TActionSequence *TStreamerInfoActions::TActionSequence::CreateSubSequence(const std::vector<Int_t> &element_ids, size_t offset)
01546 {
01547
01548
01549
01550 TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo,element_ids.size());
01551
01552 sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
01553
01554 for(UInt_t id = 0; id < element_ids.size(); ++id) {
01555 if ( element_ids[id] < 0 ) {
01556 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
01557 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
01558 iter != end;
01559 ++iter)
01560 {
01561 TConfiguration *conf = iter->fConfiguration->Copy();
01562 conf->AddToOffset(offset);
01563 sequence->AddAction( iter->fAction, conf );
01564 }
01565 } else {
01566 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
01567 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
01568 iter != end;
01569 ++iter) {
01570 if ( iter->fConfiguration->fElemId == (UInt_t)element_ids[id] ) {
01571 TConfiguration *conf = iter->fConfiguration->Copy();
01572 conf->AddToOffset(offset);
01573 sequence->AddAction( iter->fAction, conf );
01574 }
01575 }
01576 }
01577 }
01578 return sequence;
01579 }
01580
01581 void TStreamerInfoActions::TActionSequence::Print(Option_t *) const
01582 {
01583
01584
01585
01586 if (fLoopConfig) {
01587 fLoopConfig->Print();
01588 }
01589 TStreamerInfoActions::ActionContainer_t::const_iterator end = fActions.end();
01590 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = fActions.begin();
01591 iter != end;
01592 ++iter)
01593 {
01594 iter->fConfiguration->Print();
01595 }
01596 }
01597
01598