TFormLeafInfo.cxx

Go to the documentation of this file.
00001 // @(#)root/treeplayer:$Id: TFormLeafInfo.cxx 35254 2010-09-13 19:11:45Z pcanal $
00002 // Author: Philippe Canal 01/06/2004
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers and al.        *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //______________________________________________________________________________
00013 //
00014 // TTreeFormula now relies on a variety of TFormLeafInfo classes to handle the
00015 // reading of the information.  Here is the list of theses classes:
00016 //   TFormLeafInfo
00017 //   TFormLeafInfoDirect
00018 //   TFormLeafInfoNumerical
00019 //   TFormLeafInfoClones
00020 //   TFormLeafInfoCollection
00021 //   TFormLeafInfoPointer
00022 //   TFormLeafInfoMethod
00023 //   TFormLeafInfoMultiVarDim
00024 //   TFormLeafInfoMultiVarDimDirect
00025 //   TFormLeafInfoCast
00026 //
00027 // The following method are available from the TFormLeafInfo interface:
00028 //
00029 //  AddOffset(Int_t offset, TStreamerElement* element)
00030 //  GetCounterValue(TLeaf* leaf) : return the size of the array pointed to.
00031 //  GetObjectAddress(TLeafElement* leaf) : Returns the the location of the object pointed to.
00032 //  GetMultiplicity() : Returns info on the variability of the number of elements
00033 //  GetNdata(TLeaf* leaf) : Returns the number of elements
00034 //  GetNdata() : Used by GetNdata(TLeaf* leaf)
00035 //  GetValue(TLeaf *leaf, Int_t instance = 0) : Return the value
00036 //  GetValuePointer(TLeaf *leaf, Int_t instance = 0) : Returns the address of the value
00037 //  GetLocalValuePointer(TLeaf *leaf, Int_t instance = 0) : Returns the address of the value of 'this' LeafInfo
00038 //  IsString()
00039 //  ReadValue(char *where, Int_t instance = 0) : Internal function to interpret the location 'where'
00040 //  Update() : react to the possible loading of a shared library.
00041 //
00042 //
00043 
00044 #include "TFormLeafInfo.h"
00045 
00046 #include "TROOT.h"
00047 #include "TArrayI.h"
00048 #include "TClonesArray.h"
00049 #include "TError.h"
00050 #include "TInterpreter.h"
00051 #include "TLeafObject.h"
00052 #include "TMethod.h"
00053 #include "TMethodCall.h"
00054 #include "TTree.h"
00055 #include "TVirtualCollectionProxy.h"
00056 
00057 
00058 //______________________________________________________________________________
00059 //
00060 // This class is a small helper class to implement reading a data member
00061 // on an object stored in a TTree.
00062 
00063 //______________________________________________________________________________
00064 TFormLeafInfo::TFormLeafInfo(TClass* classptr, Long_t offset,
00065                              TStreamerElement* element) :
00066      fClass(classptr),fOffset(offset),fElement(element),
00067      fCounter(0), fNext(0),fMultiplicity(0)
00068 {
00069    // Constructor.
00070 
00071    if (fClass) fClassName = fClass->GetName();
00072    if (fElement) {
00073       fElementName = fElement->GetName();
00074    }
00075 }
00076 
00077 //______________________________________________________________________________
00078 TFormLeafInfo::TFormLeafInfo(const TFormLeafInfo& orig) : TObject(orig)
00079 {
00080    //Constructor.
00081 
00082    *this = orig; // default copy
00083    // change the pointers that need to be deep-copied
00084    if (fCounter) fCounter = fCounter->DeepCopy();
00085    if (fNext) fNext = fNext->DeepCopy();
00086 }
00087 
00088 //______________________________________________________________________________
00089 TFormLeafInfo* TFormLeafInfo::DeepCopy() const
00090 {
00091    // Make a complete copy of this FormLeafInfo and all its content.
00092    return new TFormLeafInfo(*this);
00093 }
00094 
00095 //______________________________________________________________________________
00096 TFormLeafInfo::~TFormLeafInfo()
00097 {
00098    // Delete this object and all its content
00099    delete fCounter;
00100    delete fNext;
00101 }
00102 
00103 
00104 //______________________________________________________________________________
00105 void TFormLeafInfo::AddOffset(Int_t offset, TStreamerElement* element)
00106 {
00107    // Increase the offset of this element.  This intended to be the offset
00108    // from the start of the object to which the data member belongs.
00109    fOffset += offset;
00110    fElement = element;
00111    if (fElement ) {
00112       //         fElementClassOwnerName = cl->GetName();
00113       fElementName.Append(".").Append(element->GetName());
00114    }
00115 }
00116 
00117 //______________________________________________________________________________
00118 Int_t TFormLeafInfo::GetArrayLength()
00119 {
00120    // Return the current length of the array.
00121 
00122    Int_t len = 1;
00123    if (fNext) len = fNext->GetArrayLength();
00124    if (fElement) {
00125       Int_t elen = fElement->GetArrayLength();
00126       if (elen || fElement->IsA() == TStreamerBasicPointer::Class() )
00127          len *= fElement->GetArrayLength();
00128    }
00129    return len;
00130 }
00131 
00132 
00133 //______________________________________________________________________________
00134 TClass* TFormLeafInfo::GetClass() const
00135 {
00136    // Get the class of the underlying data.
00137 
00138    if (fNext) return fNext->GetClass();
00139    if (fElement) return fElement->GetClassPointer();
00140    return fClass;
00141 }
00142 
00143 //______________________________________________________________________________
00144 char* TFormLeafInfo::GetObjectAddress(TLeafElement* leaf, Int_t& instance)
00145 {
00146    // Returns the the location of the object pointed to.
00147    // Modify instance if the object is part of an array.
00148 
00149    TBranchElement* branch = (TBranchElement*) leaf->GetBranch();
00150    Int_t id = branch->GetID();
00151    if (id < 0) {
00152       // Branch is a top-level branch.
00153       if (branch->GetTree()->GetMakeClass()) {
00154          // Branch belongs to a MakeClass tree.
00155          return branch->GetAddress();
00156       } else {
00157          return branch->GetObject();
00158       }
00159    }
00160    TStreamerInfo* info = branch->GetInfo();
00161    Int_t offset = 0;
00162    if (id > -1) {
00163       // Branch is *not* a top-level branch.
00164       offset = info->GetOffsets()[id];
00165    }
00166    char* address = 0;
00167    // Branch is *not* a top-level branch.
00168    if (branch->GetTree()->GetMakeClass()) {
00169       // Branch belongs to a MakeClass tree.
00170       address = (char*) branch->GetAddress();
00171    } else {
00172       address = (char*) branch->GetObject();
00173    }
00174    char* thisobj = 0;
00175    if (!address) {
00176       // FIXME: This makes no sense, if the branch address is not set, then object will not be set either.
00177       thisobj = branch->GetObject();
00178    } else {
00179       Int_t type = -1;
00180       if (id > -1) {
00181          type = info->GetNewTypes()[id];
00182       }
00183       switch (type) {
00184          case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp:
00185          case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP:
00186          case TStreamerInfo::kOffsetL + TStreamerInfo::kSTLp:
00187          case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyp:
00188          case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyP:
00189             Error("GetValuePointer", "Type (%d) not yet supported\n", type);
00190             break;
00191 
00192          case TStreamerInfo::kOffsetL + TStreamerInfo::kObject:
00193          case TStreamerInfo::kOffsetL + TStreamerInfo::kAny:
00194          case TStreamerInfo::kOffsetL + TStreamerInfo::kSTL: 
00195          {
00196             // An array of objects.
00197             Int_t index;
00198             Int_t sub_instance;
00199             Int_t len = GetArrayLength();
00200             if (len) {
00201                index = instance / len;
00202                sub_instance = instance % len;
00203             } else {
00204                index = instance;
00205                sub_instance = 0;
00206             }
00207             thisobj = address + offset + (index * fClass->Size());
00208             instance = sub_instance;
00209             break;
00210          }
00211 
00212          case TStreamerInfo::kBase:
00213          case TStreamerInfo::kObject:
00214          case TStreamerInfo::kTString:
00215          case TStreamerInfo::kTNamed:
00216          case TStreamerInfo::kTObject:
00217          case TStreamerInfo::kAny:
00218          case TStreamerInfo::kSTL:
00219             // A single object.
00220             thisobj = address + offset;
00221             break;
00222 
00223          case kBool_t:
00224          case kChar_t:
00225          case kUChar_t:
00226          case kShort_t:
00227          case kUShort_t:
00228          case kInt_t:
00229          case kUInt_t:
00230          case kLong_t:
00231          case kULong_t:
00232          case kLong64_t:
00233          case kULong64_t:
00234          case kFloat_t:
00235          case kFloat16_t:
00236          case kDouble_t:
00237          case kDouble32_t:
00238          case kchar:
00239          case TStreamerInfo::kCounter:
00240          case TStreamerInfo::kOffsetL + kBool_t:
00241          case TStreamerInfo::kOffsetL + kChar_t:
00242          case TStreamerInfo::kOffsetL + kUChar_t:
00243          case TStreamerInfo::kOffsetL + kShort_t:
00244          case TStreamerInfo::kOffsetL + kUShort_t:
00245          case TStreamerInfo::kOffsetL + kInt_t:
00246          case TStreamerInfo::kOffsetL + kUInt_t:
00247          case TStreamerInfo::kOffsetL + kLong_t:
00248          case TStreamerInfo::kOffsetL + kULong_t:
00249          case TStreamerInfo::kOffsetL + kLong64_t:
00250          case TStreamerInfo::kOffsetL + kULong64_t:
00251          case TStreamerInfo::kOffsetL + kFloat_t:
00252          case TStreamerInfo::kOffsetL + kFloat16_t:
00253          case TStreamerInfo::kOffsetL + kDouble_t:
00254          case TStreamerInfo::kOffsetL + kDouble32_t:
00255          case TStreamerInfo::kOffsetL + kchar:
00256             // A simple type, or an array of a simple type.
00257             thisobj = address + offset;
00258             break;
00259 
00260          default:
00261             // Everything else is a pointer to something.
00262             thisobj = *((char**) (address + offset));
00263             break;
00264          }
00265    }
00266    return thisobj;
00267 }
00268 
00269 //______________________________________________________________________________
00270 Int_t TFormLeafInfo::GetMultiplicity()
00271 {
00272    // Reminder of the meaning of fMultiplicity:
00273    //  -1: Only one or 0 element per entry but contains variable length array!
00274    //   0: Only one element per entry, no variable length array
00275    //   1: loop over the elements of a variable length array
00276    //   2: loop over elements of fixed length array (nData is the same for all entry)
00277 
00278    // Currently only TFormLeafInfoCast uses this field.
00279    return fMultiplicity;
00280 }
00281 
00282 Int_t TFormLeafInfo::GetNdata(TLeaf* leaf)
00283 {
00284    // Get the number of element in the entry.
00285 
00286    GetCounterValue(leaf);
00287    GetValue(leaf);
00288    return GetNdata();
00289 }
00290 
00291 //______________________________________________________________________________
00292 Int_t TFormLeafInfo::GetNdata()
00293 {
00294    // Get the number of element in the entry.
00295    if (fNext) return fNext->GetNdata();
00296    return 1;
00297 }
00298 
00299 //______________________________________________________________________________
00300 Bool_t TFormLeafInfo::HasCounter() const
00301 {
00302    // Return true if any of underlying data has a array size counter
00303 
00304    Bool_t result = kFALSE;
00305    if (fNext) result = fNext->HasCounter();
00306    return fCounter!=0 || result;
00307 }
00308 
00309 //______________________________________________________________________________
00310 Bool_t TFormLeafInfo::IsString() const
00311 {
00312    // Return true if the underlying data is a string
00313 
00314    if (fNext) return fNext->IsString();
00315    if (!fElement) return kFALSE;
00316 
00317    switch (fElement->GetNewType()) {
00318       // basic types
00319       case kChar_t:
00320          // This is new in ROOT 3.02/05
00321          return kFALSE;
00322       case TStreamerInfo::kOffsetL + kChar_t:
00323          // This is new in ROOT 3.02/05
00324          return kTRUE;
00325       case TStreamerInfo::kCharStar:
00326          return kTRUE;
00327       default:
00328          return kFALSE;
00329    }
00330 }
00331 
00332 //______________________________________________________________________________
00333 Bool_t TFormLeafInfo::IsInteger() const
00334 {
00335    // Return true if the underlying data is an integral value
00336 
00337    if (fNext) return fNext->IsInteger();
00338    if (!fElement) return kFALSE;
00339 
00340    Int_t atype = fElement->GetNewType();
00341    if (TStreamerInfo::kOffsetL < atype &&
00342        atype < TStreamerInfo::kOffsetP ) {
00343       atype -= TStreamerInfo::kOffsetL;
00344    } else if (TStreamerInfo::kOffsetP < atype &&
00345               atype < TStreamerInfo::kObject) {
00346       atype -= TStreamerInfo::kOffsetP;
00347    }
00348 
00349    switch (atype) {
00350       // basic types
00351       case kchar:
00352       case kBool_t:
00353       case kChar_t:
00354       case kUChar_t:
00355       case kShort_t:
00356       case kUShort_t:
00357       case kInt_t:
00358       case kUInt_t:
00359       case kLong_t:
00360       case kULong_t:
00361       case kLong64_t:
00362       case kULong64_t:
00363          return kTRUE;
00364       case kCharStar:
00365          return kTRUE; // For consistency with the leaf list method and proper axis setting
00366       case kFloat_t:
00367       case kFloat16_t:
00368       case kDouble_t:
00369       case kDouble32_t:
00370          return kFALSE;
00371       default:
00372          return kFALSE;
00373    }
00374 }
00375 
00376 //______________________________________________________________________________
00377 Int_t TFormLeafInfo::GetPrimaryIndex()
00378 {
00379    // Method for multiple variable dimensions.
00380    if (fNext) return fNext->GetPrimaryIndex();
00381    return -1;
00382 }
00383 
00384 //______________________________________________________________________________
00385 Int_t TFormLeafInfo::GetVarDim()
00386 {
00387    // Return the index of the dimension which varies
00388    // for each elements of an enclosing array (typically a TClonesArray)
00389    if (fNext) return fNext->GetVarDim();
00390    else return -1;
00391 }
00392 
00393 //______________________________________________________________________________
00394 Int_t TFormLeafInfo::GetVirtVarDim()
00395 {
00396    // Return the virtual index (for this expression) of the dimension which varies
00397    // for each elements of an enclosing array (typically a TClonesArray)
00398    if (fNext) return fNext->GetVirtVarDim();
00399    else return -1;
00400 }
00401 
00402 //______________________________________________________________________________
00403 Int_t TFormLeafInfo::GetSize(Int_t index)
00404 {
00405    // For the current entry, and the value 'index' for the main array,
00406    // return the size of the secondary variable dimension of the 'array'.
00407    if (fNext) return fNext->GetSize(index);
00408    else return 0;
00409 }
00410 
00411 //______________________________________________________________________________
00412 Int_t TFormLeafInfo::GetSumOfSizes()
00413 {
00414    // Total all the elements that are available for the current entry
00415    // for the secondary variable dimension.
00416    if (fNext) return fNext->GetSumOfSizes();
00417    else return 0;
00418 }
00419 
00420 //______________________________________________________________________________
00421 void TFormLeafInfo::LoadSizes(TBranch* branch)
00422 {
00423    // Load the current array sizes
00424    if (fNext) fNext->LoadSizes(branch);
00425 }
00426 
00427 //______________________________________________________________________________
00428 void TFormLeafInfo::SetPrimaryIndex(Int_t index)
00429 {
00430    // Set the primary index value
00431    if (fNext) fNext->SetPrimaryIndex(index);
00432 }
00433 
00434 //______________________________________________________________________________
00435 void TFormLeafInfo::SetSecondaryIndex(Int_t index)
00436 {
00437    // Set the primary index value
00438    if (fNext) fNext->SetSecondaryIndex(index);
00439 }
00440 
00441 //______________________________________________________________________________
00442 void TFormLeafInfo::SetSize(Int_t index, Int_t val)
00443 {
00444    // Set the current size of the arrays
00445    if (fNext) fNext->SetSize(index, val);
00446 }
00447 
00448 //______________________________________________________________________________
00449 void TFormLeafInfo::UpdateSizes(TArrayI *garr)
00450 {
00451    // Set the current sizes of the arrays
00452    if (fNext) fNext->UpdateSizes(garr);
00453 }
00454 
00455 
00456 //______________________________________________________________________________
00457 Bool_t TFormLeafInfo::Update()
00458 {
00459    // We reloading all cached information in case the underlying class
00460    // information has changed (for example when changing from the 'emulated'
00461    // class to the real class.
00462 
00463    if (fClass) {
00464       TClass * new_class = TClass::GetClass(fClassName);
00465       if (new_class==fClass) {
00466          if (fNext) fNext->Update();
00467          if (fCounter) fCounter->Update();
00468          return kFALSE;
00469       }
00470       fClass = new_class;
00471    }
00472    if (fElement && fClass) {
00473       TClass *cl = fClass;
00474       // We have to drill down the element name within the class.
00475       Int_t offset,i;
00476       TStreamerElement* element;
00477       char * current;
00478       Int_t nchname = fElementName.Length();
00479       char * work = new char[nchname+2];
00480       for (i=0, current = &(work[0]), fOffset=0; i<nchname+1;i++ ) {
00481          if (i==nchname || fElementName[i]=='.') {
00482             // A delimiter happened let's see if what we have seen
00483             // so far does point to a data member.
00484             *current = '\0';
00485             element = ((TStreamerInfo*)cl->GetStreamerInfo())->GetStreamerElement(work,offset);
00486             if (element) {
00487                Int_t type = element->GetNewType();
00488                if (type<60) {
00489                   fOffset += offset;
00490                } else if (type == TStreamerInfo::kBase ||
00491                           type == TStreamerInfo::kAny ||
00492                           type == TStreamerInfo::kObject ||
00493                           type == TStreamerInfo::kTString  ||
00494                           type == TStreamerInfo::kTNamed  ||
00495                           type == TStreamerInfo::kTObject ||
00496                           type == TStreamerInfo::kObjectp ||
00497                           type == TStreamerInfo::kObjectP ||
00498                           type == TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp ||
00499                           type == TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP ||
00500                           type == TStreamerInfo::kAnyp ||
00501                           type == TStreamerInfo::kAnyP ||
00502                           type == TStreamerInfo::kOffsetL + TStreamerInfo::kAnyp ||
00503                           type == TStreamerInfo::kOffsetL + TStreamerInfo::kAnyP ||
00504                           type == TStreamerInfo::kOffsetL + TStreamerInfo::kSTLp ||
00505                           type == TStreamerInfo::kSTL ||
00506                           type == TStreamerInfo::kSTLp ) {
00507                   fOffset += offset;
00508                   cl = element->GetClassPointer();
00509                }
00510                fElement = element;
00511                current = &(work[0]);
00512             }
00513          } else {
00514             if (i<nchname) *current++ = fElementName[i];
00515          }
00516       }
00517       delete [] work;
00518    }
00519    if (fNext) fNext->Update();
00520    if (fCounter) fCounter->Update();
00521    return kTRUE;
00522 }
00523 
00524 //______________________________________________________________________________
00525 Int_t TFormLeafInfo::GetCounterValue(TLeaf* leaf) {
00526 //  Return the size of the underlying array for the current entry in the TTree.
00527 
00528    if (!fCounter) {
00529       if (fNext && fNext->HasCounter()) {
00530          char *where = (char*)GetLocalValuePointer(leaf,0);
00531          return fNext->ReadCounterValue(where);
00532       } else return 1;
00533    }
00534    return (Int_t)fCounter->GetValue(leaf);
00535 }
00536 
00537 //______________________________________________________________________________
00538 Int_t TFormLeafInfo::ReadCounterValue(char* where)
00539 {
00540    //  Return the size of the underlying array for the current entry in the TTree.
00541 
00542    if (!fCounter) {
00543       if (fNext) {
00544          char *next = (char*)GetLocalValuePointer(where,0);
00545          return fNext->ReadCounterValue(next);
00546       } else return 1;
00547    }
00548    return (Int_t)fCounter->ReadValue(where,0);
00549 }
00550 
00551 //______________________________________________________________________________
00552 void* TFormLeafInfo::GetLocalValuePointer(TLeaf *leaf, Int_t instance)
00553 {
00554    // returns the address of the value pointed to by the
00555    // TFormLeafInfo.
00556 
00557    char *thisobj = 0;
00558    if (leaf->InheritsFrom(TLeafObject::Class()) ) {
00559       thisobj = (char*)((TLeafObject*)leaf)->GetObject();
00560    } else {
00561       thisobj = GetObjectAddress((TLeafElement*)leaf, instance); // instance might be modified
00562    }
00563    if (!thisobj) return 0;
00564    return GetLocalValuePointer(thisobj, instance);
00565 }
00566 
00567 void* TFormLeafInfo::GetValuePointer(TLeaf *leaf, Int_t instance)
00568 {
00569    // returns the address of the value pointed to by the
00570    // serie of TFormLeafInfo.
00571 
00572    char *thisobj = (char*)GetLocalValuePointer(leaf,instance);
00573    if (fNext) return fNext->GetValuePointer(thisobj,instance);
00574    else return thisobj;
00575 }
00576 
00577 //______________________________________________________________________________
00578 void* TFormLeafInfo::GetValuePointer(char *thisobj, Int_t instance)
00579 {
00580    // returns the address of the value pointed to by the
00581    // TFormLeafInfo.
00582 
00583    char *where = (char*)GetLocalValuePointer(thisobj,instance);
00584    if (fNext) return fNext->GetValuePointer(where,instance);
00585    else return where;
00586 }
00587 
00588 //______________________________________________________________________________
00589 void* TFormLeafInfo::GetLocalValuePointer(char *thisobj, Int_t instance)
00590 {
00591    // returns the address of the value pointed to by the
00592    // TFormLeafInfo.
00593 
00594    if (fElement==0) return thisobj;
00595 
00596    switch (fElement->GetNewType()) {
00597       // basic types
00598       case kBool_t:
00599       case kChar_t:
00600       case kUChar_t:
00601       case kShort_t:
00602       case kUShort_t:
00603       case kInt_t:
00604       case kUInt_t:
00605       case kLong_t:
00606       case kULong_t:
00607       case kLong64_t:
00608       case kULong64_t:
00609       case kFloat_t:
00610       case kFloat16_t:
00611       case kDouble_t:
00612       case kDouble32_t:
00613       case kchar:
00614       case TStreamerInfo::kCounter:
00615          return (Int_t*)(thisobj+fOffset);
00616 
00617          // array of basic types  array[8]
00618       case TStreamerInfo::kOffsetL + kBool_t :
00619          {Bool_t *val   = (Bool_t*)(thisobj+fOffset);      return &(val[instance]);}
00620       case TStreamerInfo::kOffsetL + kChar_t :
00621          {Char_t *val   = (Char_t*)(thisobj+fOffset);      return &(val[instance]);}
00622       case TStreamerInfo::kOffsetL + kShort_t:
00623          {Short_t *val   = (Short_t*)(thisobj+fOffset);    return &(val[instance]);}
00624       case TStreamerInfo::kOffsetL + kInt_t:
00625          {Int_t *val     = (Int_t*)(thisobj+fOffset);      return &(val[instance]);}
00626       case TStreamerInfo::kOffsetL + kLong_t:
00627          {Long_t *val    = (Long_t*)(thisobj+fOffset);     return &(val[instance]);}
00628       case TStreamerInfo::kOffsetL + kLong64_t:
00629          {Long64_t *val  = (Long64_t*)(thisobj+fOffset);   return &(val[instance]);}
00630       case TStreamerInfo::kOffsetL + kFloat_t:
00631          {Float_t *val   = (Float_t*)(thisobj+fOffset);    return &(val[instance]);}
00632       case TStreamerInfo::kOffsetL + kFloat16_t:
00633          {Float_t *val   = (Float_t*)(thisobj+fOffset);    return &(val[instance]);}
00634       case TStreamerInfo::kOffsetL + kDouble_t:
00635          {Double_t *val  = (Double_t*)(thisobj+fOffset);   return &(val[instance]);}
00636       case TStreamerInfo::kOffsetL + kDouble32_t:
00637          {Double_t *val  = (Double_t*)(thisobj+fOffset);   return &(val[instance]);}
00638       case TStreamerInfo::kOffsetL + kUChar_t:
00639          {UChar_t *val   = (UChar_t*)(thisobj+fOffset);    return &(val[instance]);}
00640       case TStreamerInfo::kOffsetL + kUShort_t:
00641          {UShort_t *val  = (UShort_t*)(thisobj+fOffset);   return &(val[instance]);}
00642       case TStreamerInfo::kOffsetL + kUInt_t:
00643          {UInt_t *val    = (UInt_t*)(thisobj+fOffset);     return &(val[instance]);}
00644       case TStreamerInfo::kOffsetL + kULong_t:
00645          {ULong_t *val   = (ULong_t*)(thisobj+fOffset);    return &(val[instance]);}
00646       case TStreamerInfo::kOffsetL + kULong64_t:
00647          {ULong64_t *val  = (ULong64_t*)(thisobj+fOffset); return &(val[instance]);}
00648 
00649 #define GET_ARRAY(TYPE_t)                                         \
00650          {                                                        \
00651             Int_t len, sub_instance, index;                       \
00652             if (fNext) len = fNext->GetArrayLength();             \
00653             else len = 1;                                         \
00654             if (len) {                                            \
00655                index = instance / len;                            \
00656                sub_instance = instance % len;                     \
00657             } else {                                              \
00658                index = instance;                                  \
00659                sub_instance = 0;                                  \
00660             }                                                     \
00661             TYPE_t **val     = (TYPE_t**)(thisobj+fOffset);       \
00662             return &((val[sub_instance])[index]);                 \
00663          }
00664 
00665          // pointer to an array of basic types  array[n]
00666       case TStreamerInfo::kOffsetP + kBool_t:    GET_ARRAY(Bool_t)
00667       case TStreamerInfo::kOffsetP + kChar_t:    GET_ARRAY(Char_t)
00668       case TStreamerInfo::kOffsetP + kShort_t:   GET_ARRAY(Short_t)
00669       case TStreamerInfo::kOffsetP + kInt_t:     GET_ARRAY(Int_t)
00670       case TStreamerInfo::kOffsetP + kLong_t:    GET_ARRAY(Long_t)
00671       case TStreamerInfo::kOffsetP + kLong64_t:  GET_ARRAY(Long64_t)
00672       case TStreamerInfo::kOffsetP + kFloat16_t:
00673       case TStreamerInfo::kOffsetP + kFloat_t:   GET_ARRAY(Float_t)
00674       case TStreamerInfo::kOffsetP + kDouble32_t:
00675       case TStreamerInfo::kOffsetP + kDouble_t:  GET_ARRAY(Double_t)
00676       case TStreamerInfo::kOffsetP + kUChar_t:   GET_ARRAY(UChar_t)
00677       case TStreamerInfo::kOffsetP + kUShort_t:  GET_ARRAY(UShort_t)
00678       case TStreamerInfo::kOffsetP + kUInt_t:    GET_ARRAY(UInt_t)
00679       case TStreamerInfo::kOffsetP + kULong_t:   GET_ARRAY(ULong_t)
00680       case TStreamerInfo::kOffsetP + kULong64_t: GET_ARRAY(ULong64_t)
00681 
00682       case TStreamerInfo::kCharStar:
00683          {char **stringp = (char**)(thisobj+fOffset); return *stringp;}
00684 
00685       case TStreamerInfo::kObjectp:
00686       case TStreamerInfo::kObjectP:
00687       case TStreamerInfo::kAnyp:
00688       case TStreamerInfo::kAnyP:
00689       case TStreamerInfo::kSTLp:
00690          {TObject **obj = (TObject**)(thisobj+fOffset);   return *obj; }
00691 
00692       case TStreamerInfo::kObject:
00693       case TStreamerInfo::kTString:
00694       case TStreamerInfo::kTNamed:
00695       case TStreamerInfo::kTObject:
00696       case TStreamerInfo::kAny:
00697       case TStreamerInfo::kBase:
00698       case TStreamerInfo::kSTL:
00699          {TObject *obj = (TObject*)(thisobj+fOffset);   return obj; }
00700 
00701       case TStreamerInfo::kOffsetL + TStreamerInfo::kTObject:
00702       case TStreamerInfo::kOffsetL + TStreamerInfo::kSTL:
00703       case TStreamerInfo::kOffsetL + TStreamerInfo::kAny: {
00704          char *loc = thisobj+fOffset;
00705 
00706          Int_t len, index, sub_instance;
00707 
00708          if (fNext) len = fNext->GetArrayLength();
00709          else len = 1;
00710          if (len) {
00711             index = instance / len;
00712             sub_instance = instance % len;
00713          } else {
00714             index = instance;
00715             sub_instance = 0;
00716          }
00717 
00718          loc += index*fElement->GetClassPointer()->Size();
00719 
00720          TObject *obj = (TObject*)(loc);
00721          return obj;
00722       }
00723 
00724       case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp:
00725       case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP:
00726       case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyp:
00727       case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyP:
00728       case TStreamerInfo::kOffsetL + TStreamerInfo::kSTLp:
00729          {TObject *obj = (TObject*)(thisobj+fOffset);   return obj; }
00730 
00731       case kOther_t:
00732       default:        return 0;
00733    }
00734 
00735 }
00736 
00737 
00738 //______________________________________________________________________________
00739 Double_t TFormLeafInfo::GetValue(TLeaf *leaf, Int_t instance)
00740 {
00741    // Return result of a leafobject method.
00742 
00743    char *thisobj = 0;
00744    if (leaf->InheritsFrom(TLeafObject::Class()) ) {
00745       thisobj = (char*)((TLeafObject*)leaf)->GetObject();
00746    } else {
00747       thisobj = GetObjectAddress((TLeafElement*)leaf, instance); // instance might be modified
00748    }
00749    if (thisobj==0) return 0;
00750    return ReadValue(thisobj,instance);
00751 }
00752 
00753 //______________________________________________________________________________
00754 Double_t TFormLeafInfo::ReadValue(char *thisobj, Int_t instance)
00755 {
00756    // Read the value at the given memory location
00757    if ( !thisobj )  {
00758       Error("ReadValue","Invalid data address: result will be wrong");
00759       return 0.0;  // Or should throw exception/print error ?
00760    }
00761    if (fNext) {
00762       char *nextobj = thisobj+fOffset;
00763       Int_t sub_instance = instance;
00764       Int_t type = fElement->GetNewType();
00765       if (type==TStreamerInfo::kOffsetL + TStreamerInfo::kObject ||
00766           type==TStreamerInfo::kOffsetL + TStreamerInfo::kSTL ||
00767           type==TStreamerInfo::kOffsetL + TStreamerInfo::kAny) {
00768          Int_t index;
00769          Int_t len = fNext->GetArrayLength();
00770          if (len) {
00771             index = instance / len;
00772             sub_instance = instance % len;
00773          } else {
00774             index = instance;
00775             sub_instance = 0;
00776          }
00777          nextobj += index*fElement->GetClassPointer()->Size();
00778       }
00779       return fNext->ReadValue(nextobj,sub_instance);
00780    }
00781    //   return fInfo->ReadValue(thisobj+fOffset,fElement->GetNewType(),instance,1);
00782    switch (fElement->GetNewType()) {
00783          // basic types
00784       case kBool_t:     return (Double_t)(*(Bool_t*)(thisobj+fOffset));
00785       case kChar_t:     return (Double_t)(*(Char_t*)(thisobj+fOffset));
00786       case kUChar_t:    return (Double_t)(*(UChar_t*)(thisobj+fOffset));
00787       case kShort_t:    return (Double_t)(*(Short_t*)(thisobj+fOffset));
00788       case kUShort_t:   return (Double_t)(*(UShort_t*)(thisobj+fOffset));
00789       case kInt_t:      return (Double_t)(*(Int_t*)(thisobj+fOffset));
00790       case kUInt_t:     return (Double_t)(*(UInt_t*)(thisobj+fOffset));
00791       case kLong_t:     return (Double_t)(*(Long_t*)(thisobj+fOffset));
00792       case kULong_t:    return (Double_t)(*(ULong_t*)(thisobj+fOffset));
00793       case kLong64_t:   return (Double_t)(*(Long64_t*)(thisobj+fOffset));
00794       case kULong64_t:  return (Double_t)(*(Long64_t*)(thisobj+fOffset)); //cannot cast to ULong64_t with VC++6
00795       case kFloat_t:    return (Double_t)(*(Float_t*)(thisobj+fOffset));
00796       case kFloat16_t:  return (Double_t)(*(Float_t*)(thisobj+fOffset));
00797       case kDouble_t:   return (Double_t)(*(Double_t*)(thisobj+fOffset));
00798       case kDouble32_t: return (Double_t)(*(Double_t*)(thisobj+fOffset));
00799       case kchar:       return (Double_t)(*(char*)(thisobj+fOffset));
00800       case TStreamerInfo::kCounter:
00801          return (Double_t)(*(Int_t*)(thisobj+fOffset));
00802 
00803          // array of basic types  array[8]
00804       case TStreamerInfo::kOffsetL + kBool_t :
00805          {Bool_t *val    = (Bool_t*)(thisobj+fOffset);    return Double_t(val[instance]);}
00806       case TStreamerInfo::kOffsetL + kChar_t :
00807          {Char_t *val    = (Char_t*)(thisobj+fOffset);    return Double_t(val[instance]);}
00808       case TStreamerInfo::kOffsetL + kShort_t:
00809          {Short_t *val   = (Short_t*)(thisobj+fOffset);   return Double_t(val[instance]);}
00810       case TStreamerInfo::kOffsetL + kInt_t:
00811          {Int_t *val     = (Int_t*)(thisobj+fOffset);     return Double_t(val[instance]);}
00812       case TStreamerInfo::kOffsetL + kLong_t:
00813          {Long_t *val    = (Long_t*)(thisobj+fOffset);    return Double_t(val[instance]);}
00814       case TStreamerInfo::kOffsetL + kLong64_t:
00815          {Long64_t *val  = (Long64_t*)(thisobj+fOffset);  return Double_t(val[instance]);}
00816       case TStreamerInfo::kOffsetL + kFloat16_t:
00817          {Float_t *val   = (Float_t*)(thisobj+fOffset);   return Double_t(val[instance]);}
00818       case TStreamerInfo::kOffsetL + kFloat_t:
00819          {Float_t *val   = (Float_t*)(thisobj+fOffset);   return Double_t(val[instance]);}
00820       case TStreamerInfo::kOffsetL + kDouble_t:
00821          {Double_t *val  = (Double_t*)(thisobj+fOffset);  return Double_t(val[instance]);}
00822       case TStreamerInfo::kOffsetL + kDouble32_t:
00823          {Double_t *val  = (Double_t*)(thisobj+fOffset);  return Double_t(val[instance]);}
00824       case TStreamerInfo::kOffsetL + kUChar_t:
00825          {UChar_t *val   = (UChar_t*)(thisobj+fOffset);   return Double_t(val[instance]);}
00826       case TStreamerInfo::kOffsetL + kUShort_t:
00827          {UShort_t *val  = (UShort_t*)(thisobj+fOffset);  return Double_t(val[instance]);}
00828       case TStreamerInfo::kOffsetL + kUInt_t:
00829          {UInt_t *val    = (UInt_t*)(thisobj+fOffset);    return Double_t(val[instance]);}
00830       case TStreamerInfo::kOffsetL + kULong_t:
00831          {ULong_t *val   = (ULong_t*)(thisobj+fOffset);   return Double_t(val[instance]);}
00832 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00833       case TStreamerInfo::kOffsetL + kULong64_t:
00834          {Long64_t *val = (Long64_t*)(thisobj+fOffset);   return Double_t(val[instance]);}
00835 #else
00836       case TStreamerInfo::kOffsetL + kULong64_t:
00837          {ULong64_t *val = (ULong64_t*)(thisobj+fOffset); return Double_t(val[instance]);}
00838 #endif
00839 
00840 #define READ_ARRAY(TYPE_t)                               \
00841          {                                               \
00842             Int_t len, sub_instance, index;              \
00843             len = GetArrayLength();                      \
00844             if (len) {                                   \
00845                index = instance / len;                   \
00846                sub_instance = instance % len;            \
00847             } else {                                     \
00848                index = instance;                         \
00849                sub_instance = 0;                         \
00850             }                                            \
00851             TYPE_t **val =(TYPE_t**)(thisobj+fOffset);   \
00852             return Double_t((val[sub_instance])[index]); \
00853          }
00854 
00855          // pointer to an array of basic types  array[n]
00856       case TStreamerInfo::kOffsetP + kBool_t:    READ_ARRAY(Bool_t)
00857       case TStreamerInfo::kOffsetP + kChar_t:    READ_ARRAY(Char_t)
00858       case TStreamerInfo::kOffsetP + kShort_t:   READ_ARRAY(Short_t)
00859       case TStreamerInfo::kOffsetP + kInt_t:     READ_ARRAY(Int_t)
00860       case TStreamerInfo::kOffsetP + kLong_t:    READ_ARRAY(Long_t)
00861       case TStreamerInfo::kOffsetP + kLong64_t:  READ_ARRAY(Long64_t)
00862       case TStreamerInfo::kOffsetP + kFloat16_t:
00863       case TStreamerInfo::kOffsetP + kFloat_t:   READ_ARRAY(Float_t)
00864       case TStreamerInfo::kOffsetP + kDouble32_t:
00865       case TStreamerInfo::kOffsetP + kDouble_t:  READ_ARRAY(Double_t)
00866       case TStreamerInfo::kOffsetP + kUChar_t:   READ_ARRAY(UChar_t)
00867       case TStreamerInfo::kOffsetP + kUShort_t:  READ_ARRAY(UShort_t)
00868       case TStreamerInfo::kOffsetP + kUInt_t:    READ_ARRAY(UInt_t)
00869       case TStreamerInfo::kOffsetP + kULong_t:   READ_ARRAY(ULong_t)
00870 #if defined(_MSC_VER) && (_MSC_VER <= 1200)
00871       case TStreamerInfo::kOffsetP + kULong64_t: READ_ARRAY(Long64_t)
00872 #else
00873       case TStreamerInfo::kOffsetP + kULong64_t: READ_ARRAY(ULong64_t)
00874 #endif
00875 
00876       case kOther_t:
00877       default:        return 0;
00878    }
00879 }
00880 
00881 //______________________________________________________________________________
00882 //
00883 // TFormLeafInfoDirect is a small helper class to implement reading a data
00884 // member on an object stored in a TTree.
00885 
00886 //______________________________________________________________________________
00887 TFormLeafInfoDirect::TFormLeafInfoDirect(TBranchElement * from) :
00888    TFormLeafInfo(from->GetInfo()->GetClass(),0,
00889                  (TStreamerElement*)from->GetInfo()->GetElems()[from->GetID()])
00890 {
00891    // Constructor.
00892 }
00893 
00894 //______________________________________________________________________________
00895 TFormLeafInfoDirect::TFormLeafInfoDirect(const TFormLeafInfoDirect& orig) :
00896    TFormLeafInfo(orig)
00897 {
00898    // Constructor.
00899 }
00900 
00901 //______________________________________________________________________________
00902 TFormLeafInfo* TFormLeafInfoDirect::DeepCopy() const
00903 {
00904    // Copy this object and its content.
00905    return new TFormLeafInfoDirect(*this);
00906 }
00907 
00908 //______________________________________________________________________________
00909 TFormLeafInfoDirect::~TFormLeafInfoDirect()
00910 {
00911    // Destructor.
00912 }
00913 
00914 //______________________________________________________________________________
00915 Double_t TFormLeafInfoDirect::ReadValue(char * /*where*/, Int_t /*instance*/)
00916 {
00917    // Read the value at the given memory location
00918    Error("ReadValue","Should not be used in a TFormLeafInfoDirect");
00919    return 0;
00920 }
00921 
00922 //______________________________________________________________________________
00923 Double_t TFormLeafInfoDirect:: GetValue(TLeaf *leaf, Int_t instance)
00924 {
00925    // Return the underlying value.
00926    return leaf->GetValue(instance);
00927 }
00928 
00929 //______________________________________________________________________________
00930 void* TFormLeafInfoDirect::GetLocalValuePointer(TLeaf *leaf, Int_t instance)
00931 {
00932    // Return the address of the underlying value.
00933    if (leaf->IsA() != TLeafElement::Class()) {
00934       return leaf->GetValuePointer();
00935    } else {
00936       return GetObjectAddress((TLeafElement*)leaf, instance); // instance might be modified
00937    }
00938 }
00939 
00940 //______________________________________________________________________________
00941 void* TFormLeafInfoDirect::GetLocalValuePointer(char *thisobj, Int_t instance)
00942 {
00943    // Note this should probably never be executed.
00944    return TFormLeafInfo::GetLocalValuePointer(thisobj,instance);
00945 }
00946 
00947 //______________________________________________________________________________
00948 //
00949 // TFormLeafInfoNumerical is a small helper class to implement reading a
00950 // numerical value inside a collection
00951 
00952 //______________________________________________________________________________
00953 TFormLeafInfoNumerical::TFormLeafInfoNumerical(EDataType kind) :
00954    TFormLeafInfo(0,0,0),
00955    fKind(kind), fIsBool(kFALSE)
00956 {
00957    // Constructor.
00958    fElement = new TStreamerElement("data","in collection", 0, fKind, "");
00959 }
00960 
00961 //______________________________________________________________________________
00962 TFormLeafInfoNumerical::TFormLeafInfoNumerical(TVirtualCollectionProxy *collection) :
00963    TFormLeafInfo(0,0,0),
00964    fKind(kNoType_t), fIsBool(kFALSE)
00965 {
00966    // Construct a TFormLeafInfo for the numerical type contained in the collection.
00967    
00968    if (collection) {
00969       fKind = (EDataType)collection->GetType();
00970       if (fKind == TStreamerInfo::kOffsetL + TStreamerInfo::kChar) {
00971          // Could be a bool
00972          if (strcmp( collection->GetCollectionClass()->GetName(), "vector<bool>") == 0 
00973              || strncmp( collection->GetCollectionClass()->GetName(), "bitset<", strlen("bitset<") ) ==0 ) {
00974             fIsBool = kTRUE;
00975             fKind = (EDataType)18;
00976          }
00977       }
00978    }
00979    fElement = new TStreamerElement("data","in collection", 0, fKind, "");
00980 }
00981 
00982 //______________________________________________________________________________
00983 TFormLeafInfoNumerical::TFormLeafInfoNumerical(const TFormLeafInfoNumerical& orig) :
00984    TFormLeafInfo(orig),
00985    fKind(orig.fKind), fIsBool(kFALSE)
00986 {
00987    // Constructor.
00988    fElement = new TStreamerElement("data","in collection", 0, fKind, "");
00989 }
00990 
00991 //______________________________________________________________________________
00992 TFormLeafInfo* TFormLeafInfoNumerical::DeepCopy() const
00993 {
00994    // Copy the object and all its content.
00995    return new TFormLeafInfoNumerical(*this);
00996 }
00997 
00998 //______________________________________________________________________________
00999 TFormLeafInfoNumerical::~TFormLeafInfoNumerical()
01000 {
01001    // Destructor
01002    delete fElement;
01003 }
01004 //______________________________________________________________________________
01005 Bool_t TFormLeafInfoNumerical::IsString() const
01006 {
01007    // Return true if the underlying data is a string
01008    
01009    if (fIsBool) return kFALSE;
01010    return TFormLeafInfo::IsString();
01011 }  
01012 
01013 //______________________________________________________________________________
01014 Bool_t TFormLeafInfoNumerical::Update()
01015 {
01016    // We reloading all cached information in case the underlying class
01017    // information has changed (for example when changing from the 'emulated'
01018    // class to the real class.
01019 
01020    //R__ASSERT(fNext==0);
01021 
01022    if (fCounter) return fCounter->Update();
01023    return kFALSE;
01024 }
01025 
01026 namespace {
01027    TStreamerElement *R__GetFakeClonesElem() {
01028       static TStreamerElement gFakeClonesElem("begin","fake",0,
01029                                               TStreamerInfo::kAny,
01030                                               "TClonesArray");
01031       return &gFakeClonesElem;
01032    }
01033 }
01034 
01035 //______________________________________________________________________________
01036 //
01037 // TFormLeafInfoClones is a small helper class to implement reading a data member
01038 // on a TClonesArray object stored in a TTree.
01039 
01040 //______________________________________________________________________________
01041 TFormLeafInfoClones::TFormLeafInfoClones(TClass* classptr, Long_t offset) :
01042    TFormLeafInfo(classptr,offset,R__GetFakeClonesElem()),fTop(kFALSE)
01043 {
01044    // Constructor.
01045 }
01046 
01047 //______________________________________________________________________________
01048 TFormLeafInfoClones::TFormLeafInfoClones(TClass* classptr, Long_t offset,
01049                                          Bool_t top) :
01050    TFormLeafInfo(classptr,offset,R__GetFakeClonesElem()),fTop(top)
01051 {
01052    // Constructor/
01053 }
01054 
01055 //______________________________________________________________________________
01056 TFormLeafInfoClones::TFormLeafInfoClones(TClass* classptr, Long_t offset,
01057                                          TStreamerElement* element,
01058                                          Bool_t top) :
01059    TFormLeafInfo(classptr,offset,element),fTop(top)
01060 {
01061    // Constructor.
01062 }
01063 
01064 //______________________________________________________________________________
01065 Int_t TFormLeafInfoClones::GetCounterValue(TLeaf* leaf)
01066 {
01067    // Return the current size of the the TClonesArray
01068 
01069    if (!fCounter) {
01070       TClass *clonesClass = TClonesArray::Class();
01071       Int_t c_offset;
01072       TStreamerElement *counter = ((TStreamerInfo*)clonesClass->GetStreamerInfo())->GetStreamerElement("fLast",c_offset);
01073       fCounter = new TFormLeafInfo(clonesClass,c_offset,counter);
01074    }
01075    return (Int_t)fCounter->ReadValue((char*)GetLocalValuePointer(leaf)) + 1;
01076 }
01077 
01078 //______________________________________________________________________________
01079 Int_t TFormLeafInfoClones::ReadCounterValue(char* where)
01080 {
01081    // Return the current size of the the TClonesArray
01082 
01083    if (!fCounter) {
01084       TClass *clonesClass = TClonesArray::Class();
01085       Int_t c_offset;
01086       TStreamerElement *counter = ((TStreamerInfo*)clonesClass->GetStreamerInfo())->GetStreamerElement("fLast",c_offset);
01087       fCounter = new TFormLeafInfo(clonesClass,c_offset,counter);
01088    }
01089    return (Int_t)fCounter->ReadValue(where) + 1;
01090 }
01091 
01092 //______________________________________________________________________________
01093 Double_t TFormLeafInfoClones::ReadValue(char *where, Int_t instance)
01094 {
01095    // Return the value of the underlying data member inside the
01096    // clones array.
01097 
01098    if (fNext==0) return 0;
01099    Int_t len,index,sub_instance;
01100    len = fNext->GetArrayLength();
01101    if (len) {
01102       index = instance / len;
01103       sub_instance = instance % len;
01104    } else {
01105       index = instance;
01106       sub_instance = 0;
01107    }
01108    TClonesArray * clones = (TClonesArray*)where;
01109    if (!clones) return 0;
01110    // Note we take advantage of having only one physically variable
01111    // dimension:
01112    char * obj = (char*)clones->UncheckedAt(index);
01113    return fNext->ReadValue(obj,sub_instance);
01114 }
01115 
01116 //______________________________________________________________________________
01117 void* TFormLeafInfoClones::GetLocalValuePointer(TLeaf *leaf, Int_t /*instance*/)
01118 {
01119    // Return the pointer to the clonesArray
01120 
01121    TClonesArray * clones;
01122    if (fTop) {
01123       if (leaf->InheritsFrom(TLeafObject::Class()) ) {
01124          clones = (TClonesArray*)((TLeafObject*)leaf)->GetObject();
01125       } else {
01126          clones = (TClonesArray*)((TBranchElement*)leaf->GetBranch())->GetObject();
01127       }
01128    } else {
01129       clones = (TClonesArray*)TFormLeafInfo::GetLocalValuePointer(leaf);
01130    }
01131    return clones;
01132 }
01133 
01134 //______________________________________________________________________________
01135 void* TFormLeafInfoClones::GetLocalValuePointer(char *where, Int_t instance)
01136 {
01137    // Return the address of the underlying current value
01138    return TFormLeafInfo::GetLocalValuePointer(where,instance);
01139 }
01140 
01141 //______________________________________________________________________________
01142 Double_t TFormLeafInfoClones::GetValue(TLeaf *leaf, Int_t instance)
01143 {
01144    // Return the value of the underlying data member inside the
01145    // clones array.
01146 
01147    if (fNext==0) return 0;
01148    Int_t len,index,sub_instance;
01149    len = (fNext->fElement==0)? 0 : fNext->GetArrayLength();
01150    Int_t primary = fNext->GetPrimaryIndex();
01151    if (len) {
01152       index = instance / len;
01153       sub_instance = instance % len;
01154    } else if (primary>=0) {
01155       index = primary;
01156       sub_instance = instance;
01157    } else {
01158       index = instance;
01159       sub_instance = 0;
01160    }
01161    TClonesArray *clones = (TClonesArray*)GetLocalValuePointer(leaf);
01162 
01163    // Note we take advantage of having only one physically variable
01164    // dimension:
01165    char * obj = (char*)clones->UncheckedAt(index);
01166    return fNext->ReadValue(obj,sub_instance);
01167 }
01168 
01169 //______________________________________________________________________________
01170 void * TFormLeafInfoClones::GetValuePointer(TLeaf *leaf, Int_t instance)
01171 {
01172    // Return the pointer to the clonesArray
01173 
01174    TClonesArray * clones = (TClonesArray*)GetLocalValuePointer(leaf);
01175    if (fNext) {
01176       // Same as in TFormLeafInfoClones::GetValue
01177       Int_t len,index,sub_instance;
01178       len = (fNext->fElement==0)? 0 : fNext->GetArrayLength();
01179       if (len) {
01180          index = instance / len;
01181          sub_instance = instance % len;
01182       } else {
01183          index = instance;
01184          sub_instance = 0;
01185       }
01186       return fNext->GetValuePointer((char*)clones->UncheckedAt(index),
01187                                     sub_instance);
01188    }
01189    return clones;
01190 }
01191 
01192 //______________________________________________________________________________
01193 void * TFormLeafInfoClones::GetValuePointer(char *where, Int_t instance)
01194 {
01195    // Return the pointer to the clonesArray
01196 
01197    TClonesArray * clones = (TClonesArray*) where;
01198    if (fNext) {
01199       // Same as in TFormLeafInfoClones::GetValue
01200       Int_t len,index,sub_instance;
01201       len = (fNext->fElement==0)? 0 : fNext->GetArrayLength();
01202       if (len) {
01203          index = instance / len;
01204          sub_instance = instance % len;
01205       } else {
01206          index = instance;
01207          sub_instance = 0;
01208       }
01209       return fNext->GetValuePointer((char*)clones->UncheckedAt(index),
01210                                     sub_instance);
01211    }
01212    return clones;
01213 }
01214 
01215 //______________________________________________________________________________
01216 //
01217 // TFormLeafInfoCollectionObject is a small helper class to implement reading a data member
01218 // on a TClonesArray object stored in a TTree.
01219 
01220 //______________________________________________________________________________
01221 TFormLeafInfoCollectionObject::TFormLeafInfoCollectionObject(TClass* classptr, Bool_t top) :
01222    TFormLeafInfo(classptr,0,R__GetFakeClonesElem()),fTop(top)
01223 {
01224    // Constructor.
01225 }
01226 
01227 //______________________________________________________________________________
01228 Int_t TFormLeafInfoCollectionObject::GetCounterValue(TLeaf* /* leaf */)
01229 {
01230    // Return the current size of the the TClonesArray
01231 
01232    return 1;
01233 }
01234 
01235 //______________________________________________________________________________
01236 Double_t TFormLeafInfoCollectionObject::ReadValue(char * /* where */, Int_t /* instance */)
01237 {
01238    // Return the value of the underlying data member inside the
01239    // clones array.
01240 
01241    R__ASSERT(0);
01242    return 0;
01243 }
01244 
01245 //______________________________________________________________________________
01246 void* TFormLeafInfoCollectionObject::GetLocalValuePointer(TLeaf *leaf, Int_t /*instance*/)
01247 {
01248    // Return the pointer to the clonesArray
01249 
01250    void* collection;
01251    if (fTop) {
01252       if (leaf->InheritsFrom(TLeafObject::Class()) ) {
01253          collection = ((TLeafObject*)leaf)->GetObject();
01254       } else {
01255          collection = ((TBranchElement*)leaf->GetBranch())->GetObject();
01256       }
01257    } else {
01258       collection = TFormLeafInfo::GetLocalValuePointer(leaf);
01259    }
01260    return collection;
01261 }
01262 
01263 //______________________________________________________________________________
01264 void* TFormLeafInfoCollectionObject::GetLocalValuePointer(char *where, Int_t instance)
01265 {
01266    // Return the address of the underlying current value
01267    return TFormLeafInfo::GetLocalValuePointer(where,instance);
01268 }
01269 
01270 //______________________________________________________________________________
01271 Double_t TFormLeafInfoCollectionObject::GetValue(TLeaf *leaf, Int_t instance)
01272 {
01273    // Return the value of the underlying data member inside the
01274    // clones array.
01275 
01276    char * obj = (char*)GetLocalValuePointer(leaf);
01277 
01278    if (fNext==0) return 0;
01279    return fNext->ReadValue(obj,instance);
01280 }
01281 
01282 //______________________________________________________________________________
01283 void * TFormLeafInfoCollectionObject::GetValuePointer(TLeaf *leaf, Int_t instance)
01284 {
01285    // Return the pointer to the clonesArray
01286 
01287    void *collection = GetLocalValuePointer(leaf);
01288    if (fNext) {
01289       return fNext->GetValuePointer((char*)collection,instance);
01290    }
01291    return collection;
01292 }
01293 
01294 //______________________________________________________________________________
01295 void * TFormLeafInfoCollectionObject::GetValuePointer(char *where, Int_t instance)
01296 {
01297    // Return the pointer to the clonesArray
01298 
01299    if (fNext) {
01300       return fNext->GetValuePointer(where,instance);
01301    }
01302    return where;
01303 }
01304 
01305 //______________________________________________________________________________
01306 //
01307 // TFormLeafInfoCollection is a small helper class to implement reading a data
01308 // member on a generic collection object stored in a TTree.
01309 
01310 //______________________________________________________________________________
01311 TFormLeafInfoCollection::TFormLeafInfoCollection(TClass* classptr,
01312                                                  Long_t offset,
01313                                                  TStreamerElement* element,
01314                                                  Bool_t top) :
01315    TFormLeafInfo(classptr,offset,element),
01316    fTop(top),
01317    fCollClass( 0),
01318    fCollProxy( 0),
01319    fLocalElement( 0)
01320 {
01321    // Cosntructor.
01322 
01323    if (element) {
01324       fCollClass = element->GetClass();
01325    } else if (classptr) {
01326       fCollClass = classptr;
01327    }
01328    if (fCollClass
01329        && fCollClass!=TClonesArray::Class()
01330        && fCollClass->GetCollectionProxy()) {
01331 
01332       fCollProxy = fCollClass->GetCollectionProxy()->Generate();
01333       fCollClassName = fCollClass->GetName();
01334    }
01335 }
01336 
01337 //______________________________________________________________________________
01338 TFormLeafInfoCollection::TFormLeafInfoCollection(TClass* motherclassptr,
01339                                                  Long_t offset,
01340                                                  TClass* elementclassptr,
01341                                                  Bool_t top) :
01342    TFormLeafInfo(motherclassptr,offset,
01343                  new TStreamerElement("collection","in class",
01344                                       0,
01345                                       TStreamerInfo::kAny,
01346                                       elementclassptr
01347                                       ? elementclassptr->GetName()
01348                                       : ( motherclassptr
01349                                           ? motherclassptr->GetName()
01350                                           : "Unknwon")
01351                                       ) ),
01352    fTop(top),
01353    fCollClass( 0),
01354    fCollProxy( 0) ,
01355    fLocalElement( fElement )
01356 {
01357    // Constructor.
01358 
01359    if (elementclassptr) {
01360       fCollClass = elementclassptr;
01361    } else if (motherclassptr) {
01362       fCollClass = motherclassptr;
01363    }
01364    if (fCollClass
01365        && fCollClass!=TClonesArray::Class()
01366        && fCollClass->GetCollectionProxy())
01367       {
01368          fCollProxy = fCollClass->GetCollectionProxy()->Generate();
01369          fCollClassName = fCollClass->GetName();
01370       }
01371 }
01372 
01373 //______________________________________________________________________________
01374 TFormLeafInfoCollection::TFormLeafInfoCollection() :
01375    TFormLeafInfo(),
01376    fTop(kFALSE),
01377    fCollClass( 0),
01378    fCollProxy( 0),
01379    fLocalElement( 0)
01380 {
01381    // Constructor.
01382 }
01383 
01384 //______________________________________________________________________________
01385 TFormLeafInfoCollection::TFormLeafInfoCollection(const TFormLeafInfoCollection& orig) :
01386    TFormLeafInfo(orig),
01387    fTop( orig.fTop),
01388    fCollClass( orig.fCollClass ),
01389    fCollClassName( orig.fCollClassName ),
01390    fCollProxy( orig.fCollProxy ? orig.fCollProxy->Generate() : 0 ),
01391    fLocalElement( 0 )
01392 {
01393    // Constructor.
01394 }
01395 
01396 //______________________________________________________________________________
01397 TFormLeafInfoCollection::~TFormLeafInfoCollection()
01398 {
01399    // Destructor.
01400    delete fCollProxy;
01401    delete fLocalElement;
01402 }
01403 
01404 //______________________________________________________________________________
01405 TFormLeafInfo* TFormLeafInfoCollection::DeepCopy() const
01406 {
01407    // Copy of the object and its content.
01408    return new TFormLeafInfoCollection(*this);
01409 }
01410 
01411 //______________________________________________________________________________
01412 Bool_t TFormLeafInfoCollection::Update()
01413 {
01414    // We reloading all cached information in case the underlying class
01415    // information has changed (for example when changing from the 'emulated'
01416    // class to the real class.
01417 
01418    Bool_t changed = kFALSE;
01419    TClass * new_class = TClass::GetClass(fCollClassName);
01420    if (new_class!=fCollClass) {
01421       delete fCollProxy; fCollProxy = 0;
01422       fCollClass = new_class;
01423       if (fCollClass && fCollClass->GetCollectionProxy()) {
01424          fCollProxy = fCollClass->GetCollectionProxy()->Generate();
01425       }
01426       changed = kTRUE;
01427    }
01428    return changed || TFormLeafInfo::Update();
01429 }
01430 
01431 //______________________________________________________________________________
01432 Bool_t TFormLeafInfoCollection::HasCounter() const
01433 {
01434    // Return true if the underlying data has a array size counter
01435    return fCounter!=0 || fCollProxy!=0;
01436 }
01437 
01438 //______________________________________________________________________________
01439 Int_t TFormLeafInfoCollection::GetCounterValue(TLeaf* leaf)
01440 {
01441    // Return the current size of the the TClonesArray
01442 
01443    void *ptr = GetLocalValuePointer(leaf);
01444 
01445    if (fCounter) { return (Int_t)fCounter->ReadValue((char*)ptr); }
01446    
01447    R__ASSERT(fCollProxy);
01448    if (ptr==0) return 0;
01449    TVirtualCollectionProxy::TPushPop helper(fCollProxy, ptr);
01450    return (Int_t)fCollProxy->Size();
01451 }
01452 
01453 //______________________________________________________________________________
01454 Int_t TFormLeafInfoCollection::ReadCounterValue(char* where)
01455 {
01456    //  Return the size of the underlying array for the current entry in the TTree.
01457 
01458    if (fCounter) { return (Int_t)fCounter->ReadValue(where); }
01459    R__ASSERT(fCollProxy);
01460    if (where==0) return 0;
01461    void *ptr = GetLocalValuePointer(where,0);
01462    TVirtualCollectionProxy::TPushPop helper(fCollProxy, ptr);
01463    return (Int_t)fCollProxy->Size();
01464 }
01465 
01466 //______________________________________________________________________________
01467 Int_t TFormLeafInfoCollection::GetCounterValue(TLeaf* leaf, Int_t instance)
01468 {
01469    // Return the current size of the the TClonesArray
01470 
01471    void *ptr = GetLocalValuePointer(leaf,instance);
01472    if (fCounter) {
01473       return (Int_t)fCounter->ReadValue((char*)ptr);
01474    }
01475    R__ASSERT(fCollProxy);
01476    if (ptr==0) return 0;
01477    TVirtualCollectionProxy::TPushPop helper(fCollProxy, ptr);
01478    return (Int_t)fCollProxy->Size();
01479 }
01480 
01481 //______________________________________________________________________________
01482 Double_t TFormLeafInfoCollection::ReadValue(char *where, Int_t instance)
01483 {
01484    // Return the value of the underlying data member inside the
01485    // clones array.
01486 
01487    if (fNext==0) return 0;
01488    UInt_t len,index,sub_instance;
01489    len = (fNext->fElement==0)? 0 : fNext->GetArrayLength(); 
01490    Int_t primary = fNext->GetPrimaryIndex();
01491    if (len) {
01492       index = instance / len;
01493       sub_instance = instance % len;
01494    } else if (primary>=0) {
01495       index = primary;
01496       sub_instance = instance;
01497    } else {
01498       index = instance;
01499       sub_instance = 0;
01500    }
01501 
01502    R__ASSERT(fCollProxy);
01503    void *ptr = GetLocalValuePointer(where,instance);
01504    TVirtualCollectionProxy::TPushPop helper(fCollProxy, ptr);
01505 
01506    // Note we take advantage of having only one physically variable
01507    // dimension:
01508 
01509    char * obj = (char*)fCollProxy->At(index);
01510    if (fCollProxy->HasPointers()) obj = *(char**)obj;
01511    return fNext->ReadValue(obj,sub_instance);
01512 }
01513 
01514 //______________________________________________________________________________
01515 void* TFormLeafInfoCollection::GetLocalValuePointer(TLeaf *leaf, Int_t /*instance*/)
01516 {
01517    // Return the pointer to the clonesArray
01518 
01519    void *collection;
01520    if (fTop) {
01521       if (leaf->InheritsFrom(TLeafObject::Class()) ) {
01522          collection = ((TLeafObject*)leaf)->GetObject();
01523       } else {
01524          collection = ((TBranchElement*)leaf->GetBranch())->GetObject();
01525       }
01526    } else {
01527       collection = TFormLeafInfo::GetLocalValuePointer(leaf);
01528    }
01529    return collection;
01530 }
01531 
01532 //______________________________________________________________________________
01533 void* TFormLeafInfoCollection::GetLocalValuePointer(char *where, Int_t instance)
01534 {
01535    // Return the address of the local value
01536    return TFormLeafInfo::GetLocalValuePointer(where,instance);
01537 }
01538 
01539 //______________________________________________________________________________
01540 Double_t TFormLeafInfoCollection::GetValue(TLeaf *leaf, Int_t instance)
01541 {
01542    // Return the value of the underlying data member inside the
01543    // clones array.
01544 
01545    if (fNext==0) return 0;
01546    Int_t len,index,sub_instance;
01547    len = (fNext->fElement==0)? 0 : fNext->GetArrayLength();
01548    Int_t primary = fNext->GetPrimaryIndex();
01549    if (len) {
01550       index = instance / len;
01551       sub_instance = instance % len;
01552    } else if (primary>=0) {
01553       index = primary;
01554       sub_instance = instance;
01555    } else {
01556       index = instance;
01557       sub_instance = 0;
01558    }
01559 
01560    R__ASSERT(fCollProxy);
01561    void *coll = GetLocalValuePointer(leaf);
01562    TVirtualCollectionProxy::TPushPop helper(fCollProxy,coll);
01563 
01564    // Note we take advantage of having only one physically variable
01565    // dimension:
01566    char * obj = (char*)fCollProxy->At(index);
01567    if (obj==0) return 0;
01568    if (fCollProxy->HasPointers()) obj = *(char**)obj;
01569    if (obj==0) return 0;
01570    return fNext->ReadValue(obj,sub_instance);
01571 }
01572 
01573 //______________________________________________________________________________
01574 void * TFormLeafInfoCollection::GetValuePointer(TLeaf *leaf, Int_t instance)
01575 {
01576    // Return the pointer to the clonesArray
01577 
01578    R__ASSERT(fCollProxy);
01579 
01580    void *collection = GetLocalValuePointer(leaf);
01581 
01582    if (fNext) {
01583       // Same as in TFormLeafInfoClones::GetValue
01584       Int_t len,index,sub_instance;
01585       if (fNext->fElement &&
01586          (fNext->fNext || !fNext->IsString()) ) {
01587          len = fNext->GetArrayLength();
01588       } else {
01589          len = 0;
01590       }
01591       if (len) {
01592          index = instance / len;
01593          sub_instance = instance % len;
01594       } else {
01595          index = instance;
01596          sub_instance = 0;
01597       }
01598       TVirtualCollectionProxy::TPushPop helper(fCollProxy,collection);
01599       char * obj = (char*)fCollProxy->At(index);
01600       if (fCollProxy->HasPointers()) obj = *(char**)obj;
01601       return fNext->GetValuePointer(obj,sub_instance);
01602    }
01603    return collection;
01604 }
01605 
01606 //______________________________________________________________________________
01607 void * TFormLeafInfoCollection::GetValuePointer(char *where, Int_t instance)
01608 {
01609    // Return the pointer to the clonesArray
01610 
01611    R__ASSERT(fCollProxy);
01612 
01613    void *collection = where;
01614 
01615    if (fNext) {
01616       // Same as in TFormLeafInfoClones::GetValue
01617       Int_t len,index,sub_instance;
01618       len = (fNext->fElement==0)? 0 : fNext->GetArrayLength();
01619       if (len) {
01620          index = instance / len;
01621          sub_instance = instance % len;
01622       } else {
01623          index = instance;
01624          sub_instance = 0;
01625       }
01626       TVirtualCollectionProxy::TPushPop helper(fCollProxy,collection);
01627       char * obj = (char*)fCollProxy->At(index);
01628       if (fCollProxy->HasPointers()) obj = *(char**)obj;
01629       return fNext->GetValuePointer(obj,sub_instance);
01630    }
01631    return collection;
01632 }
01633 
01634 //______________________________________________________________________________
01635 //
01636 // TFormLeafInfoCollectionSize is used to return the size of a collection
01637 //
01638 //______________________________________________________________________________
01639 
01640 //______________________________________________________________________________
01641 TFormLeafInfoCollectionSize::TFormLeafInfoCollectionSize(TClass* classptr) :
01642    TFormLeafInfo(), fCollClass(classptr), fCollProxy(0)
01643 {
01644    // Constructor.
01645    if (fCollClass
01646        && fCollClass!=TClonesArray::Class()
01647        && fCollClass->GetCollectionProxy()) {
01648 
01649       fCollProxy = fCollClass->GetCollectionProxy()->Generate();
01650       fCollClassName = fCollClass->GetName();
01651    }
01652 }
01653 
01654 //______________________________________________________________________________
01655 TFormLeafInfoCollectionSize::TFormLeafInfoCollectionSize(
01656    TClass* classptr,Long_t offset,TStreamerElement* element) :
01657    TFormLeafInfo(classptr,offset,element), fCollClass(element->GetClassPointer()), fCollProxy(0)
01658 {
01659    // Constructor.
01660 
01661    if (fCollClass
01662        && fCollClass!=TClonesArray::Class()
01663        && fCollClass->GetCollectionProxy()) {
01664 
01665       fCollProxy = fCollClass->GetCollectionProxy()->Generate();
01666       fCollClassName = fCollClass->GetName();
01667    }
01668 }
01669 
01670 //______________________________________________________________________________
01671 TFormLeafInfoCollectionSize::TFormLeafInfoCollectionSize() :
01672    TFormLeafInfo(), fCollClass(0), fCollProxy(0)
01673 {
01674    // Constructor.
01675 }
01676 
01677 //______________________________________________________________________________
01678 TFormLeafInfoCollectionSize::TFormLeafInfoCollectionSize(
01679    const TFormLeafInfoCollectionSize& orig) :  TFormLeafInfo(),
01680       fCollClass(orig.fCollClass),
01681       fCollClassName(orig.fCollClassName),
01682       fCollProxy(orig.fCollProxy?orig.fCollProxy->Generate():0)
01683 {
01684    // Constructor.
01685 }
01686 
01687 //______________________________________________________________________________
01688 TFormLeafInfoCollectionSize::~TFormLeafInfoCollectionSize()
01689 {
01690    // Destructor.
01691    delete fCollProxy;
01692 }
01693 
01694 //______________________________________________________________________________
01695 TFormLeafInfo* TFormLeafInfoCollectionSize::DeepCopy() const
01696 {
01697    // Copy the object and all of its content.
01698    return new TFormLeafInfoCollectionSize(*this);
01699 }
01700 
01701 //______________________________________________________________________________
01702 Bool_t TFormLeafInfoCollectionSize::Update()
01703 {
01704    // We reloading all cached information in case the underlying class
01705    // information has changed (for example when changing from the 'emulated'
01706    // class to the real class.
01707 
01708    Bool_t changed = kFALSE;
01709    TClass *new_class = TClass::GetClass(fCollClassName);
01710    if (new_class!=fCollClass) {
01711       delete fCollProxy; fCollProxy = 0;
01712       fCollClass = new_class;
01713       if (fCollClass && fCollClass->GetCollectionProxy()) {
01714          fCollProxy = fCollClass->GetCollectionProxy()->Generate();
01715       }
01716       changed = kTRUE;
01717    }
01718    return changed;
01719 }
01720 
01721 //______________________________________________________________________________
01722 void *TFormLeafInfoCollectionSize::GetValuePointer(TLeaf * /* leaf */, Int_t  /* instance */)
01723 {
01724    // Not implemented.
01725 
01726    Error("GetValuePointer","This should never be called");
01727    return 0;
01728 }
01729 
01730 //______________________________________________________________________________
01731 void *TFormLeafInfoCollectionSize::GetValuePointer(char  * /* from */, Int_t  /* instance */)
01732 {
01733    // Not implemented.
01734 
01735    Error("GetValuePointer","This should never be called");
01736    return 0;
01737 }
01738 
01739 //______________________________________________________________________________
01740 void *TFormLeafInfoCollectionSize::GetLocalValuePointer(TLeaf * /* leaf */, Int_t  /* instance */)
01741 {
01742    // Not implemented.
01743 
01744    Error("GetLocalValuePointer","This should never be called");
01745    return 0;
01746 }
01747 
01748 //______________________________________________________________________________
01749 void *TFormLeafInfoCollectionSize::GetLocalValuePointer( char * /* from */, Int_t  /* instance */)
01750 {
01751    // Not implemented.
01752 
01753    Error("GetLocalValuePointer","This should never be called");
01754    return 0;
01755 }
01756 
01757 //______________________________________________________________________________
01758 Double_t  TFormLeafInfoCollectionSize::ReadValue(char *where, Int_t /* instance */)
01759 {
01760    // Return the value of the underlying pointer data member
01761 
01762    R__ASSERT(fCollProxy);
01763    if (where==0) return 0;
01764    void *ptr = fElement ? TFormLeafInfo::GetLocalValuePointer(where) : where;
01765    TVirtualCollectionProxy::TPushPop helper(fCollProxy, ptr);
01766    return (Int_t)fCollProxy->Size();
01767 }
01768 
01769 //______________________________________________________________________________
01770 //
01771 // TFormLeafInfoPointer is a small helper class to implement reading a data
01772 // member by following a pointer inside a branch of TTree.
01773 //______________________________________________________________________________
01774 
01775 //______________________________________________________________________________
01776 TFormLeafInfoPointer::TFormLeafInfoPointer(TClass* classptr,
01777                                            Long_t offset,
01778                                            TStreamerElement* element) :
01779    TFormLeafInfo(classptr,offset,element)
01780 {
01781    // Constructor.
01782 }
01783 
01784 //______________________________________________________________________________
01785 TFormLeafInfoPointer::TFormLeafInfoPointer(const TFormLeafInfoPointer& orig) :
01786    TFormLeafInfo(orig)
01787 {
01788    // Constructor.
01789 }
01790 
01791 //______________________________________________________________________________
01792 TFormLeafInfo* TFormLeafInfoPointer::DeepCopy() const
01793 {
01794    // Copy the object and all of its contnet.
01795    return new TFormLeafInfoPointer(*this);
01796 }
01797 
01798 
01799 //______________________________________________________________________________
01800 Double_t  TFormLeafInfoPointer::ReadValue(char *where, Int_t instance)
01801 {
01802    // Return the value of the underlying pointer data member
01803 
01804    if (!fNext) return 0;
01805    char * whereoffset = where+fOffset;
01806    switch (fElement->GetNewType()) {
01807       // basic types
01808       case TStreamerInfo::kObjectp:
01809       case TStreamerInfo::kObjectP:
01810       case TStreamerInfo::kAnyp:
01811       case TStreamerInfo::kAnyP:
01812       case TStreamerInfo::kSTLp:
01813       {TObject **obj = (TObject**)(whereoffset);
01814       return obj && *obj ? fNext->ReadValue((char*)*obj,instance) : 0; }
01815 
01816       case TStreamerInfo::kObject:
01817       case TStreamerInfo::kTString:
01818       case TStreamerInfo::kTNamed:
01819       case TStreamerInfo::kTObject:
01820       case TStreamerInfo::kAny:
01821       case TStreamerInfo::kBase:
01822       case TStreamerInfo::kSTL:
01823          {
01824             TObject *obj = (TObject*)(whereoffset);
01825             return fNext->ReadValue((char*)obj,instance);
01826          }
01827 
01828       case TStreamerInfo::kOffsetL + TStreamerInfo::kTObject:
01829       case TStreamerInfo::kOffsetL + TStreamerInfo::kSTL:
01830       case TStreamerInfo::kOffsetL + TStreamerInfo::kAny:
01831          {
01832             Int_t len, index, sub_instance;
01833 
01834             if (fNext) len = fNext->GetArrayLength();
01835             else len = 1;
01836             if (len) {
01837                index = instance / len;
01838                sub_instance = instance % len;
01839             } else {
01840                index = instance;
01841                sub_instance = 0;
01842             }
01843 
01844             whereoffset += index*fElement->GetClassPointer()->Size();
01845 
01846             TObject *obj = (TObject*)(whereoffset);
01847             return fNext->ReadValue((char*)obj,sub_instance);
01848          }
01849 
01850       case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectp:
01851       case TStreamerInfo::kOffsetL + TStreamerInfo::kObjectP:
01852       case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyp:
01853       case TStreamerInfo::kOffsetL + TStreamerInfo::kAnyP:
01854       case TStreamerInfo::kOffsetL + TStreamerInfo::kSTLp:
01855          {
01856             TObject *obj = (TObject*)(whereoffset);
01857             return fNext->ReadValue((char*)obj,instance);
01858          }
01859 
01860       case kOther_t:
01861       default:        return 0;
01862    }
01863 
01864 }
01865 
01866 //______________________________________________________________________________
01867 Double_t  TFormLeafInfoPointer::GetValue(TLeaf *leaf, Int_t instance)
01868 {
01869    // Return the value of the underlying pointer data member
01870 
01871    if (!fNext) return 0;
01872    char * where = (char*)GetLocalValuePointer(leaf,instance);
01873    if (where==0) return 0;
01874    return fNext->ReadValue(where,instance);
01875 }
01876 
01877 //______________________________________________________________________________
01878 //
01879 // TFormLeafInfoMethod is a small helper class to implement executing a method
01880 // of an object stored in a TTree
01881 
01882 //______________________________________________________________________________
01883 TFormLeafInfoMethod::TFormLeafInfoMethod( TClass* classptr,
01884                                           TMethodCall *method) :
01885    TFormLeafInfo(classptr,0,0),fMethod(method),
01886    fResult(0), fCopyFormat(),fDeleteFormat(),fValuePointer(0),fIsByValue(kFALSE)
01887 {
01888    // Constructor.
01889 
01890    if (method) {
01891       fMethodName = method->GetMethodName();
01892       fParams = method->GetParams();
01893       TMethodCall::EReturnType r = fMethod->ReturnType();
01894       if (r == TMethodCall::kOther) {
01895          const char* rtype = fMethod->GetMethod()->GetReturnTypeName();
01896          Long_t rprop = fMethod->GetMethod()->Property();
01897          if (rtype[strlen(rtype)-1]!='*' &&
01898              rtype[strlen(rtype)-1]!='&' &&
01899              !(rprop & (kIsPointer|kIsReference)) ) {
01900             fCopyFormat = "new ";
01901             fCopyFormat += rtype;
01902             fCopyFormat += "(*(";
01903             fCopyFormat += rtype;
01904             fCopyFormat += "*)0x%lx)";
01905 
01906             fDeleteFormat  = "delete (";
01907             fDeleteFormat += rtype;
01908             fDeleteFormat += "*)0x%lx";
01909 
01910             fIsByValue = kTRUE;
01911          }
01912       }
01913    }
01914 }
01915 
01916 //______________________________________________________________________________
01917 TFormLeafInfoMethod::TFormLeafInfoMethod(const TFormLeafInfoMethod& orig)
01918    : TFormLeafInfo(orig)
01919 {
01920    // Constructor.
01921 
01922    fMethodName = orig.fMethodName;
01923    fParams = orig.fParams ;
01924    fResult = orig.fResult;
01925    if (orig.fMethod) {
01926       fMethod = new TMethodCall(fClass,fMethodName,fParams);
01927    } else {
01928       fMethod = 0;
01929    }
01930    fCopyFormat = orig.fCopyFormat;
01931    fDeleteFormat = orig.fDeleteFormat;
01932    fValuePointer = 0;
01933    fIsByValue = orig.fIsByValue;
01934 }
01935 
01936 //______________________________________________________________________________
01937 TFormLeafInfoMethod::~TFormLeafInfoMethod()
01938 {
01939    // Destructor.
01940 
01941    if (fValuePointer) {
01942       gInterpreter->Calc(Form(fDeleteFormat.Data(),fValuePointer));
01943    }
01944    delete fMethod;
01945 }
01946 
01947 //______________________________________________________________________________
01948 TFormLeafInfo* TFormLeafInfoMethod::DeepCopy() const
01949 {
01950    // Copy the object and all its content.
01951 
01952    return new TFormLeafInfoMethod(*this);
01953 }
01954 
01955 //______________________________________________________________________________
01956 TClass* TFormLeafInfoMethod::GetClass() const
01957 {
01958    // Return the type of the underlying return value
01959 
01960    if (fNext) return fNext->GetClass();
01961    TMethodCall::EReturnType r = fMethod->ReturnType();
01962    if (r!=TMethodCall::kOther) return 0;
01963    TString return_type = gInterpreter->TypeName(fMethod->GetMethod()->GetReturnTypeName());
01964    return TClass::GetClass(return_type.Data());
01965 }
01966 
01967 //______________________________________________________________________________
01968 Bool_t TFormLeafInfoMethod::IsInteger() const
01969 {
01970    // Return true if the return value is integral.
01971 
01972    TMethodCall::EReturnType r = fMethod->ReturnType();
01973    if (r == TMethodCall::kLong) {
01974       return kTRUE;
01975    } else return kFALSE;
01976 }
01977 
01978 //______________________________________________________________________________
01979 Bool_t TFormLeafInfoMethod::IsString() const
01980 {
01981    // Return true if the return value is a string.
01982 
01983    if (fNext) return fNext->IsString();
01984 
01985    TMethodCall::EReturnType r = fMethod->ReturnType();
01986    return (r==TMethodCall::kString);
01987 }
01988 
01989 //______________________________________________________________________________
01990 Bool_t TFormLeafInfoMethod::Update()
01991 {
01992    // We reloading all cached information in case the underlying class
01993    // information has changed (for example when changing from the 'emulated'
01994    // class to the real class.
01995 
01996    if (!TFormLeafInfo::Update()) return kFALSE;
01997    delete fMethod;
01998    fMethod = new TMethodCall(fClass, fMethodName, fParams);
01999    return kTRUE;
02000 }
02001 
02002 //______________________________________________________________________________
02003 void *TFormLeafInfoMethod::GetLocalValuePointer( TLeaf *from,
02004                                                  Int_t instance)
02005 {
02006    // This is implemented here because some compiler want ALL the
02007    // signature of an overloaded function to be re-implemented.
02008    return TFormLeafInfo::GetLocalValuePointer( from, instance);
02009 }
02010 
02011 //______________________________________________________________________________
02012 void *TFormLeafInfoMethod::GetLocalValuePointer(char *from,
02013                                                 Int_t /*instance*/)
02014 {
02015    // Return the address of the lcoal underlying value.
02016 
02017    void *thisobj = from;
02018    if (!thisobj) return 0;
02019 
02020    TMethodCall::EReturnType r = fMethod->ReturnType();
02021    fResult = 0;
02022 
02023    if (r == TMethodCall::kLong) {
02024       Long_t l;
02025       fMethod->Execute(thisobj, l);
02026       fResult = (Double_t) l;
02027       // Get rid of temporary return object.
02028       gInterpreter->ClearStack();
02029       return &fResult;
02030 
02031    } else if (r == TMethodCall::kDouble) {
02032       Double_t d;
02033       fMethod->Execute(thisobj, d);
02034       fResult = (Double_t) d;
02035       // Get rid of temporary return object.
02036       gInterpreter->ClearStack();
02037       return &fResult;
02038 
02039    } else if (r == TMethodCall::kString) {
02040       char *returntext = 0;
02041       fMethod->Execute(thisobj,&returntext);
02042       gInterpreter->ClearStack();
02043       return returntext;
02044 
02045    } else if (r == TMethodCall::kOther) {
02046       char * char_result = 0;
02047       if (fIsByValue) {
02048          if (fValuePointer) {
02049             gROOT->ProcessLine(Form(fDeleteFormat.Data(),fValuePointer));
02050             fValuePointer = 0;
02051          }
02052       }
02053       fMethod->Execute(thisobj, &char_result);
02054       if (fIsByValue) {
02055          fValuePointer = (char*)gInterpreter->Calc(Form(fCopyFormat.Data(),char_result));
02056          char_result = (char*)fValuePointer;
02057       }
02058       gInterpreter->ClearStack();
02059       return char_result;
02060 
02061    }
02062    return 0;
02063 }
02064 
02065 //______________________________________________________________________________
02066 Double_t TFormLeafInfoMethod::ReadValue(char *where, Int_t instance)
02067 {
02068    // Execute the method on the given address
02069 
02070    void *thisobj = where;
02071    if (!thisobj) return 0;
02072 
02073    TMethodCall::EReturnType r = fMethod->ReturnType();
02074    Double_t result = 0;
02075 
02076    if (r == TMethodCall::kLong) {
02077       Long_t l;
02078       fMethod->Execute(thisobj, l);
02079       result = (Double_t) l;
02080 
02081    } else if (r == TMethodCall::kDouble) {
02082       Double_t d;
02083       fMethod->Execute(thisobj, d);
02084       result = (Double_t) d;
02085 
02086    } else if (r == TMethodCall::kString) {
02087       char *returntext = 0;
02088       fMethod->Execute(thisobj,&returntext);
02089       result = (long) returntext;
02090 
02091    } else if (fNext) {
02092       char * char_result = 0;
02093       fMethod->Execute(thisobj, &char_result);
02094       result = fNext->ReadValue(char_result,instance);
02095 
02096    } else fMethod->Execute(thisobj);
02097 
02098    // Get rid of temporary return object.
02099    gInterpreter->ClearStack();
02100    return result;
02101 }
02102 
02103 //______________________________________________________________________________
02104 //
02105 // TFormLeafInfoMultiVarDim is a helper class to implement reading a
02106 // data member on a variable size array inside a TClonesArray object stored in
02107 // a TTree.  This is the version used when the data member is inside a
02108 // non-splitted object.
02109 
02110 //______________________________________________________________________________
02111 TFormLeafInfoMultiVarDim::TFormLeafInfoMultiVarDim( TClass* classptr,
02112                                                     Long_t offset,
02113                                                     TStreamerElement* element,
02114                                                     TFormLeafInfo* parent) :
02115    TFormLeafInfo(classptr,offset,element),fNsize(0),fCounter2(0),fSumOfSizes(0),
02116    fDim(0),fVirtDim(-1),fPrimaryIndex(-1),fSecondaryIndex(-1)
02117 {
02118    // Constructor.
02119 
02120    if (element && element->InheritsFrom(TStreamerBasicPointer::Class())) {
02121       TStreamerBasicPointer * elem = (TStreamerBasicPointer*)element;
02122 
02123       Int_t counterOffset;
02124       TStreamerElement* counter = ((TStreamerInfo*)classptr->GetStreamerInfo())->GetStreamerElement(elem->GetCountName(),counterOffset);
02125       if (!parent) return;
02126       fCounter2 = parent->DeepCopy();
02127       TFormLeafInfo ** next = &(fCounter2->fNext);
02128       while(*next != 0) next = &( (*next)->fNext);
02129       *next = new TFormLeafInfo(classptr,counterOffset,counter);
02130 
02131    } else Error("Constructor","Called without a proper TStreamerElement");
02132 }
02133 
02134 //______________________________________________________________________________
02135 TFormLeafInfoMultiVarDim::TFormLeafInfoMultiVarDim() :
02136    TFormLeafInfo(0,0,0),fNsize(0),fCounter2(0),fSumOfSizes(0),
02137    fDim(0),fVirtDim(-1),fPrimaryIndex(-1),fSecondaryIndex(-1)
02138 {
02139    // Constructor.
02140 }
02141 
02142 //______________________________________________________________________________
02143 TFormLeafInfoMultiVarDim::TFormLeafInfoMultiVarDim(const TFormLeafInfoMultiVarDim& orig) : TFormLeafInfo(orig)
02144 {
02145    // Constructor.
02146 
02147    fNsize = orig.fNsize;
02148    fSizes.Copy(fSizes);
02149    fCounter2 = orig.fCounter2?orig.fCounter2->DeepCopy():0;
02150    fSumOfSizes = orig.fSumOfSizes;
02151    fDim = orig.fDim;
02152    fVirtDim = orig.fVirtDim;
02153    fPrimaryIndex = orig.fPrimaryIndex;
02154    fSecondaryIndex = orig.fSecondaryIndex;
02155 }
02156 
02157 //______________________________________________________________________________
02158 TFormLeafInfo* TFormLeafInfoMultiVarDim::DeepCopy() const
02159 {
02160    // Copy the object and all its content.
02161    return new TFormLeafInfoMultiVarDim(*this);
02162 }
02163 
02164 //______________________________________________________________________________
02165 TFormLeafInfoMultiVarDim:: ~TFormLeafInfoMultiVarDim()
02166 {
02167    // Destructor.
02168 
02169    delete fCounter2;
02170 }
02171 
02172 /* The proper indexing and unwinding of index is done by prior leafinfo in the chain. */
02173 //virtual Double_t  TFormLeafInfoMultiVarDim::ReadValue(char *where, Int_t instance = 0) {
02174 //   return TFormLeafInfo::ReadValue(where,instance);
02175 //}
02176 
02177 //______________________________________________________________________________
02178 void TFormLeafInfoMultiVarDim::LoadSizes(TBranch* branch)
02179 {
02180    // Load the current array sizes.
02181 
02182    if (fElement) {
02183       TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
02184       if (fCounter) fNsize = (Int_t)fCounter->GetValue(leaf);
02185       else fNsize = fCounter2->GetCounterValue(leaf);
02186       if (fNsize > fSizes.GetSize()) fSizes.Set(fNsize);
02187       fSumOfSizes = 0;
02188       for (Int_t i=0; i<fNsize; i++) {
02189          Int_t size = (Int_t)fCounter2->GetValue(leaf,i);
02190          fSumOfSizes += size;
02191          fSizes.AddAt( size, i );
02192       }
02193       return;
02194    }
02195    if (!fCounter2 || !fCounter) return;
02196    TBranchElement *br = dynamic_cast<TBranchElement*>(branch);
02197    R__ASSERT(br);
02198    fNsize = br->GetBranchCount()->GetNdata();
02199    if (fNsize > fSizes.GetSize()) fSizes.Set(fNsize);
02200    fSumOfSizes = 0;
02201    for (Int_t i=0; i<fNsize; i++) {
02202       Int_t size = (Int_t)fCounter2->GetValue((TLeaf*)br->GetBranchCount2()->GetListOfLeaves()->At(0),i);
02203       fSumOfSizes += size;
02204       fSizes.AddAt( size, i );
02205    }
02206 }
02207 
02208 //______________________________________________________________________________
02209 Int_t TFormLeafInfoMultiVarDim::GetPrimaryIndex()
02210 {
02211    // Return the index vlaue of the primary index.
02212    return fPrimaryIndex;
02213 }
02214 
02215 //______________________________________________________________________________
02216 Int_t TFormLeafInfoMultiVarDim::GetSize(Int_t index)
02217 {
02218    // Return the size of the requested sub-array.
02219    return fSizes.At(index);
02220 }
02221 
02222 //______________________________________________________________________________
02223 void TFormLeafInfoMultiVarDim::SetPrimaryIndex(Int_t index)
02224 {
02225    // Set the current value of the primary index.
02226    fPrimaryIndex = index;
02227 }
02228 
02229 //______________________________________________________________________________
02230 void TFormLeafInfoMultiVarDim::SetSecondaryIndex(Int_t index)
02231 {
02232    // Set the current value of the primary index.
02233    fSecondaryIndex = index;
02234 }
02235 
02236 //______________________________________________________________________________
02237 void TFormLeafInfoMultiVarDim::SetSize(Int_t index, Int_t val)
02238 {
02239    // Set the sizes of the sub-array.
02240    fSumOfSizes += (val - fSizes.At(index));
02241    fSizes.AddAt(val,index);
02242 }
02243 
02244 //______________________________________________________________________________
02245 Int_t TFormLeafInfoMultiVarDim::GetSumOfSizes()
02246 {
02247    // Get the total size.
02248    return fSumOfSizes;
02249 }
02250 
02251 //______________________________________________________________________________
02252 Double_t TFormLeafInfoMultiVarDim::GetValue(TLeaf * /*leaf*/,
02253                                             Int_t /*instance*/)
02254 {
02255    /* The proper indexing and unwinding of index need to be done by prior leafinfo in the chain. */
02256    Error("GetValue","This should never be called");
02257    return 0;
02258 }
02259 
02260 
02261 //______________________________________________________________________________
02262 Int_t TFormLeafInfoMultiVarDim::GetVarDim()
02263 {
02264    // Return the index of the dimension which varies
02265    // for each elements of an enclosing array (typically a TClonesArray)
02266    return fDim;
02267 }
02268 
02269 //______________________________________________________________________________
02270 Int_t TFormLeafInfoMultiVarDim::GetVirtVarDim()
02271 {
02272    // Return the virtual index (for this expression) of the dimension which varies
02273    // for each elements of an enclosing array (typically a TClonesArray)
02274    return fVirtDim;
02275 }
02276 
02277 //______________________________________________________________________________
02278 Bool_t TFormLeafInfoMultiVarDim::Update()
02279 {
02280    // We reloading all cached information in case the underlying class
02281    // information has changed (for example when changing from the 'emulated'
02282    // class to the real class.
02283 
02284    Bool_t res = TFormLeafInfo::Update();
02285    if (fCounter2) fCounter2->Update();
02286    return res;
02287 }
02288 
02289 //______________________________________________________________________________
02290 void TFormLeafInfoMultiVarDim::UpdateSizes(TArrayI *garr)
02291 {
02292    // Update the sizes of the arrays.
02293 
02294    if (!garr) return;
02295    if (garr->GetSize()<fNsize) garr->Set(fNsize);
02296    for (Int_t i=0; i<fNsize; i++) {
02297       Int_t local = fSizes.At(i);
02298       Int_t global = garr->At(i);
02299       if (global==0 || local<global) global = local;
02300       garr->AddAt(global,i);
02301    }
02302 }
02303 
02304 //______________________________________________________________________________
02305 //
02306 // TFormLeafInfoMultiVarDimDirect is a small helper class to implement reading
02307 // a data member on a variable size array inside a TClonesArray object stored
02308 // in a TTree.  This is the version used for split access
02309 //______________________________________________________________________________
02310 
02311 //______________________________________________________________________________
02312 TFormLeafInfoMultiVarDimDirect::TFormLeafInfoMultiVarDimDirect() :
02313    TFormLeafInfoMultiVarDim()
02314 {
02315    // Constructor.
02316 }
02317 
02318 //______________________________________________________________________________
02319 TFormLeafInfoMultiVarDimDirect::TFormLeafInfoMultiVarDimDirect(const TFormLeafInfoMultiVarDimDirect& orig) :
02320    TFormLeafInfoMultiVarDim(orig)
02321 {
02322    // Constructor.
02323 }
02324 
02325 //______________________________________________________________________________
02326 TFormLeafInfo* TFormLeafInfoMultiVarDimDirect::DeepCopy() const
02327 {
02328    // Copy the object and all its content.
02329    return new TFormLeafInfoMultiVarDimDirect(*this);
02330 }
02331 
02332 //______________________________________________________________________________
02333 Double_t TFormLeafInfoMultiVarDimDirect::GetValue(TLeaf *leaf, Int_t instance)
02334 {
02335    // Return the undersying value.
02336    return ((TLeafElement*)leaf)->GetValueSubArray(fPrimaryIndex,instance);
02337 }
02338 
02339 //______________________________________________________________________________
02340 Double_t TFormLeafInfoMultiVarDimDirect::ReadValue(char * /*where*/, Int_t /*instance*/)
02341 {
02342    // Not implemented.
02343 
02344    Error("ReadValue","This should never be called");
02345    return 0;
02346 }
02347 
02348 //______________________________________________________________________________
02349 //
02350 // TFormLeafInfoMultiVarDimCollection is a small helper class to implement reading
02351 // a data member on a variable size array inside a TClonesArray object stored
02352 // in a TTree.  This is the version used for split access
02353 
02354 //______________________________________________________________________________
02355 TFormLeafInfoMultiVarDimCollection::TFormLeafInfoMultiVarDimCollection(
02356    TClass* motherclassptr,
02357    Long_t offset,
02358    TClass* elementclassptr,
02359    TFormLeafInfo *parent) :
02360    TFormLeafInfoMultiVarDim(motherclassptr,offset,
02361                  new TStreamerElement("collection","in class",
02362                                       0,
02363                                       TStreamerInfo::kAny,
02364                                       elementclassptr
02365                                       ? elementclassptr->GetName()
02366                                       : ( motherclassptr
02367                                           ? motherclassptr->GetName()
02368                                           : "Unknwon")
02369                                           )
02370                                           )
02371 {
02372    // Constructor.
02373    R__ASSERT(parent);
02374    fCounter = parent->DeepCopy();
02375    fCounter2 = parent->DeepCopy();
02376    TFormLeafInfo ** next = &(fCounter2->fNext);
02377    while(*next != 0) next = &( (*next)->fNext);
02378    *next = new TFormLeafInfoCollectionSize(elementclassptr);
02379 }
02380 
02381 //______________________________________________________________________________
02382 TFormLeafInfoMultiVarDimCollection::TFormLeafInfoMultiVarDimCollection(
02383    TClass* motherclassptr,
02384    Long_t offset,
02385    TStreamerElement* element,
02386    TFormLeafInfo *parent) :
02387    TFormLeafInfoMultiVarDim(motherclassptr,offset,element)
02388 {
02389    // Constructor.
02390    R__ASSERT(parent && element);
02391    fCounter = parent->DeepCopy();
02392    fCounter2 = parent->DeepCopy();
02393    TFormLeafInfo ** next = &(fCounter2->fNext);
02394    while(*next != 0) next = &( (*next)->fNext);
02395    *next = new TFormLeafInfoCollectionSize(motherclassptr,offset,element);
02396 }
02397 
02398 //______________________________________________________________________________
02399 TFormLeafInfoMultiVarDimCollection::TFormLeafInfoMultiVarDimCollection() :
02400    TFormLeafInfoMultiVarDim()
02401 {
02402    // Constructor.
02403 }
02404 
02405 //______________________________________________________________________________
02406 TFormLeafInfoMultiVarDimCollection::TFormLeafInfoMultiVarDimCollection(
02407    const TFormLeafInfoMultiVarDimCollection& orig) :
02408    TFormLeafInfoMultiVarDim(orig)
02409 {
02410    // Constructor.
02411 }
02412 
02413 //______________________________________________________________________________
02414 TFormLeafInfo* TFormLeafInfoMultiVarDimCollection::DeepCopy() const
02415 {
02416    // Copy the object and all its content.
02417    return new TFormLeafInfoMultiVarDimCollection(*this);
02418 }
02419 
02420 //______________________________________________________________________________
02421 Double_t TFormLeafInfoMultiVarDimCollection::GetValue(TLeaf * /* leaf */,
02422                                                       Int_t /* instance */)
02423 {
02424    /* The proper indexing and unwinding of index need to be done by prior leafinfo in the chain. */
02425    Error("GetValue","This should never be called");
02426    return 0;
02427 }
02428 
02429 //______________________________________________________________________________
02430 void TFormLeafInfoMultiVarDimCollection::LoadSizes(TBranch* branch)
02431 {
02432    // Load the current array sizes.
02433 
02434    R__ASSERT(fCounter2);
02435 
02436    TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
02437    fNsize = (Int_t)fCounter->GetCounterValue(leaf);
02438 
02439    if (fNsize > fSizes.GetSize()) fSizes.Set(fNsize);
02440    fSumOfSizes = 0;
02441    for (Int_t i=0; i<fNsize; i++) {
02442       Int_t size = (Int_t)fCounter2->GetValue(leaf,i);
02443       fSumOfSizes += size;
02444       fSizes.AddAt( size, i );
02445    }
02446    return;
02447 }
02448 
02449 //______________________________________________________________________________
02450 Double_t TFormLeafInfoMultiVarDimCollection::ReadValue(char *where, Int_t instance)
02451 {
02452    // Return the value of the underlying data.
02453    if (fSecondaryIndex>=0) {
02454       UInt_t len = fNext->GetArrayLength();
02455       if (len) {
02456          instance = fSecondaryIndex*len;
02457       } else {
02458          instance = fSecondaryIndex;
02459       }
02460    }
02461    return fNext->ReadValue(where,instance);
02462 }
02463 
02464 //______________________________________________________________________________
02465 //
02466 // TFormLeafInfoMultiVarDimClones is a small helper class to implement reading
02467 // a data member on a variable size array inside a TClonesArray object stored
02468 // in a TTree.  This is the version used for split access
02469 
02470 //______________________________________________________________________________
02471 TFormLeafInfoMultiVarDimClones::TFormLeafInfoMultiVarDimClones(
02472    TClass* motherclassptr,
02473    Long_t offset,
02474    TClass* elementclassptr,
02475    TFormLeafInfo *parent) :
02476    TFormLeafInfoMultiVarDim(motherclassptr,offset,
02477                  new TStreamerElement("clones","in class",
02478                                       0,
02479                                       TStreamerInfo::kAny,
02480                                       elementclassptr
02481                                       ? elementclassptr->GetName()
02482                                       : ( motherclassptr
02483                                           ? motherclassptr->GetName()
02484                                           : "Unknwon")
02485                                           )
02486                                           )
02487 {
02488    // Constructor.
02489 
02490    R__ASSERT(parent);
02491    fCounter = parent->DeepCopy();
02492    fCounter2 = parent->DeepCopy();
02493    TFormLeafInfo ** next = &(fCounter2->fNext);
02494    while(*next != 0) next = &( (*next)->fNext);
02495    *next = new TFormLeafInfoClones(elementclassptr);
02496 }
02497 
02498 //______________________________________________________________________________
02499 TFormLeafInfoMultiVarDimClones::TFormLeafInfoMultiVarDimClones(
02500    TClass* motherclassptr,
02501    Long_t offset,
02502    TStreamerElement* element,
02503    TFormLeafInfo *parent) :
02504    TFormLeafInfoMultiVarDim(motherclassptr,offset,element)
02505 {
02506    // Constructor.
02507 
02508    R__ASSERT(parent && element);
02509    fCounter = parent->DeepCopy();
02510    fCounter2 = parent->DeepCopy();
02511    TFormLeafInfo ** next = &(fCounter2->fNext);
02512    while(*next != 0) next = &( (*next)->fNext);
02513    *next = new TFormLeafInfoClones(motherclassptr,offset,element);
02514 }
02515 
02516 //______________________________________________________________________________
02517 TFormLeafInfoMultiVarDimClones::TFormLeafInfoMultiVarDimClones() :
02518    TFormLeafInfoMultiVarDim()
02519 {
02520    // Constructor.
02521 }
02522 
02523 //______________________________________________________________________________
02524 TFormLeafInfoMultiVarDimClones::TFormLeafInfoMultiVarDimClones(
02525    const TFormLeafInfoMultiVarDimClones& orig) :
02526    TFormLeafInfoMultiVarDim(orig)
02527 {
02528    // Constructor.
02529 }
02530 
02531 //______________________________________________________________________________
02532 TFormLeafInfo* TFormLeafInfoMultiVarDimClones::DeepCopy() const
02533 {
02534    // Copy the object and all its data.
02535    return new TFormLeafInfoMultiVarDimClones(*this);
02536 }
02537 
02538 //______________________________________________________________________________
02539 Double_t TFormLeafInfoMultiVarDimClones::GetValue(TLeaf * /* leaf */,
02540                                                       Int_t /* instance */)
02541 {
02542    /* The proper indexing and unwinding of index need to be done by prior leafinfo in the chain. */
02543    Error("GetValue","This should never be called");
02544    return 0;
02545 }
02546 
02547 //______________________________________________________________________________
02548 void TFormLeafInfoMultiVarDimClones::LoadSizes(TBranch* branch)
02549 {
02550    // Load the current array sizes.
02551 
02552    R__ASSERT(fCounter2);
02553 
02554    TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
02555    fNsize = (Int_t)fCounter->GetCounterValue(leaf);
02556 
02557    if (fNsize > fSizes.GetSize()) fSizes.Set(fNsize);
02558    fSumOfSizes = 0;
02559    for (Int_t i=0; i<fNsize; i++) {
02560       TClonesArray *clones = (TClonesArray*)fCounter2->GetValuePointer(leaf,i);
02561       Int_t size = clones->GetEntries();
02562       fSumOfSizes += size;
02563       fSizes.AddAt( size, i );
02564    }
02565    return;
02566 }
02567 
02568 //______________________________________________________________________________
02569 Double_t TFormLeafInfoMultiVarDimClones::ReadValue(char *where, Int_t instance)
02570 {
02571    // Return the value of the underlying data.
02572 
02573    if (fSecondaryIndex>=0) {
02574       UInt_t len = fNext->GetArrayLength();
02575       if (len) {
02576          instance = fSecondaryIndex*len;
02577       } else {
02578          instance = fSecondaryIndex;
02579       }
02580    }
02581    return fNext->ReadValue(where,instance);
02582 }
02583 
02584 //______________________________________________________________________________
02585 //
02586 // TFormLeafInfoCast is a small helper class to implement casting an object to
02587 // a different type (equivalent to dynamic_cast)
02588 //______________________________________________________________________________
02589 
02590 //______________________________________________________________________________
02591 TFormLeafInfoCast::TFormLeafInfoCast(TClass* classptr, TClass* casted) :
02592    TFormLeafInfo(classptr),fCasted(casted),fGoodCast(kTRUE)
02593 {
02594    // Constructor.
02595 
02596    if (casted) { fCastedName = casted->GetName(); }
02597    fMultiplicity = -1;
02598    fIsTObject = fClass->InheritsFrom(TObject::Class()) && fCasted->IsLoaded();
02599 }
02600 
02601 //______________________________________________________________________________
02602 TFormLeafInfoCast::TFormLeafInfoCast(const TFormLeafInfoCast& orig) :
02603    TFormLeafInfo(orig)
02604 {
02605    // Constructor.
02606 
02607    fCasted = orig.fCasted;
02608    fCastedName = orig.fCastedName;
02609    fGoodCast = orig.fGoodCast;
02610    fIsTObject = orig.fIsTObject;
02611 }
02612 
02613 //______________________________________________________________________________
02614 TFormLeafInfo* TFormLeafInfoCast::DeepCopy() const
02615 {
02616    // Copy the object and all its content.
02617 
02618    return new TFormLeafInfoCast(*this);
02619 }
02620 
02621 //______________________________________________________________________________
02622 TFormLeafInfoCast::~TFormLeafInfoCast()
02623 {
02624    // Destructor.
02625 }
02626 
02627 // Currently only implemented in TFormLeafInfoCast
02628 Int_t TFormLeafInfoCast::GetNdata()
02629 {
02630    // Get the number of element in the entry.
02631 
02632    if (!fGoodCast) return 0;
02633    if (fNext) return fNext->GetNdata();
02634    return 1;
02635 }
02636 
02637 //______________________________________________________________________________
02638 Double_t TFormLeafInfoCast::ReadValue(char *where, Int_t instance)
02639 {
02640    // Read the value at the given memory location
02641 
02642    if (!fNext) return 0;
02643 
02644    // First check that the real class inherits from the
02645    // casted class
02646    // First assume TObject ...
02647    if ( fIsTObject && !((TObject*)where)->InheritsFrom(fCasted) ) {
02648       fGoodCast = kFALSE;
02649       return 0;
02650    } else {
02651       // We know we have a TBranchElement and we need to find out the
02652       // real class name.
02653    }
02654    fGoodCast = kTRUE;
02655    return fNext->ReadValue(where,instance);
02656 }
02657 
02658 //______________________________________________________________________________
02659 Bool_t TFormLeafInfoCast::Update()
02660 {
02661    // We reloading all cached information in case the underlying class
02662    // information has changed (for example when changing from the 'emulated'
02663    // class to the real class.
02664 
02665    if (fCasted) {
02666       TClass * new_class = TClass::GetClass(fCastedName);
02667       if (new_class!=fCasted) {
02668          fCasted = new_class;
02669       }
02670    }
02671    return TFormLeafInfo::Update();
02672 }
02673 
02674 //______________________________________________________________________________
02675 //
02676 // TFormLeafTTree is a small helper class to implement reading 
02677 // from the containing TTree object itself.
02678 //______________________________________________________________________________
02679 
02680 TFormLeafInfoTTree::TFormLeafInfoTTree(TTree *tree, const char *alias, TTree *current) :
02681 TFormLeafInfo( TTree::Class(), 0, 0 ), fTree(tree),fCurrent(current),fAlias(alias)
02682 {
02683    // Constructor.
02684 
02685    if (fCurrent==0) fCurrent = fTree->GetFriend(alias);
02686 }
02687 
02688 TFormLeafInfoTTree::TFormLeafInfoTTree(const TFormLeafInfoTTree& orig) :
02689    TFormLeafInfo(orig)
02690 {
02691    // Copy Constructor.
02692    fTree    = orig.fTree;
02693    fAlias   = orig.fAlias;
02694    fCurrent = orig.fCurrent;
02695 }
02696 
02697 TFormLeafInfoTTree::~TFormLeafInfoTTree()
02698 {
02699    // Default destructor.
02700 
02701 }
02702 
02703 TFormLeafInfo* TFormLeafInfoTTree::DeepCopy() const 
02704 {
02705    // Copy the object and all its content.
02706 
02707    return new TFormLeafInfoTTree(*this);
02708 }
02709 
02710 //______________________________________________________________________________
02711 void* TFormLeafInfoTTree::GetLocalValuePointer(TLeaf *, Int_t instance)
02712 {
02713    // returns the address of the value pointed to by the
02714    // TFormLeafInfo.
02715 
02716    return GetLocalValuePointer((char*)fCurrent,instance);
02717 }
02718 
02719 //______________________________________________________________________________
02720 Double_t TFormLeafInfoTTree::GetValue(TLeaf *, Int_t instance)
02721 {
02722    // Return result of a leafobject method.
02723 
02724    return ReadValue((char*)fCurrent,instance);
02725 }
02726 
02727 //______________________________________________________________________________
02728 Double_t TFormLeafInfoTTree::ReadValue(char *thisobj, Int_t instance)
02729 {
02730    // Return result of a leafobject method.
02731 
02732    if (fElement) return TFormLeafInfo::ReadValue(thisobj,instance);
02733    else if (fNext) return fNext->ReadValue(thisobj,instance);
02734    else return 0;
02735 }
02736 
02737 //______________________________________________________________________________
02738 Bool_t TFormLeafInfoTTree::Update() 
02739 {
02740    // Update after a change of file in a chain
02741    
02742    if (fAlias.Length() && fAlias != fTree->GetName()) {
02743       fCurrent = fTree->GetFriend(fAlias.Data());
02744    }
02745    return fCurrent && TFormLeafInfo::Update();
02746 }

Generated on Tue Jul 5 15:42:59 2011 for ROOT_528-00b_version by  doxygen 1.5.1