TStreamerElement.cxx

Go to the documentation of this file.
00001 // @(#)root/meta:$Id: TStreamerElement.cxx 36926 2010-11-25 06:24:12Z pcanal $
00002 // Author: Rene Brun   12/10/2000
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
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 //                                                                      //
00015 //////////////////////////////////////////////////////////////////////////
00016 
00017 
00018 #include "TROOT.h"
00019 #include "TStreamerElement.h"
00020 #include "TVirtualStreamerInfo.h"
00021 #include "TClass.h"
00022 #include "TClassEdit.h"
00023 #include "TClassStreamer.h"
00024 #include "TBaseClass.h"
00025 #include "TDataMember.h"
00026 #include "TDataType.h"
00027 #include "TMethodCall.h"
00028 #include "TRealData.h"
00029 #include "TFolder.h"
00030 #include "TRef.h"
00031 #include "TInterpreter.h"
00032 #include "TError.h"
00033 #include "TDataType.h"
00034 #include "TVirtualMutex.h"
00035 #include <iostream>
00036 
00037 #include <string>
00038 namespace std {} using namespace std;
00039 
00040 const Int_t kMaxLen = 1024;
00041 static TString gIncludeName(kMaxLen);
00042 
00043 extern void *gMmallocDesc;
00044 
00045 //______________________________________________________________________________
00046 static TStreamerBasicType *InitCounter(const char *countClass, const char *countName, TObject *directive)
00047 {
00048    // Helper function to initialize the 'index/counter' value of
00049    // the Pointer streamerElements.  If directive is a StreamerInfo and it correspond to the 
00050    // same class a 'countClass' the streamerInfo is used instead of the current StreamerInfo of the TClass
00051    // for 'countClass'.
00052    
00053    TStreamerBasicType *counter = 0;
00054    
00055    if (directive && directive->InheritsFrom(TVirtualStreamerInfo::Class()) && strcmp(directive->GetName(),countClass)==0) {
00056       
00057       TVirtualStreamerInfo *info = (TVirtualStreamerInfo*)directive;
00058       TStreamerElement *element = (TStreamerElement *)info->GetElements()->FindObject(countName);
00059       if (!element) return 0;
00060       if (element->IsA() != TStreamerBasicType::Class()) return 0;
00061       counter = (TStreamerBasicType*)element;
00062       
00063    } else {
00064    
00065       TClass *cl = TClass::GetClass(countClass);
00066       if (cl==0) return 0;
00067       counter = TVirtualStreamerInfo::GetElementCounter(countName,cl);
00068    }
00069        
00070    //at this point the counter may be declared to skip
00071    if (counter) {
00072       if (counter->GetType() < TVirtualStreamerInfo::kCounter) counter->SetType(TVirtualStreamerInfo::kCounter);
00073    }
00074    return counter;
00075 }
00076 
00077 //______________________________________________________________________________
00078 static void GetRange(const char *comments, Double_t &xmin, Double_t &xmax, Double_t &factor)
00079 {
00080    // Parse comments to search for a range specifier of the style:
00081    //  [xmin,xmax] or [xmin,xmax,nbits]
00082    //  [0,1]
00083    //  [-10,100];
00084    //  [-pi,pi], [-pi/2,pi/4],[-2pi,2*pi]
00085    //  [-10,100,16]
00086    //  [0,0,8]
00087    // if nbits is not specified, or nbits <2 or nbits>32 it is set to 32
00088    // if (xmin==0 and xmax==0 and nbits <=16) the double word will be converted
00089    // to a float and its mantissa truncated to nbits significative bits.
00090    //
00091    //  see comments in TBufferFile::WriteDouble32.
00092 
00093    const Double_t kPi =3.14159265358979323846 ;
00094    factor = xmin = xmax = 0;
00095    if (!comments) return;
00096    const char *left = strstr(comments,"[");
00097    if (!left) return;
00098    const char *right = strstr(left,"]");
00099    if (!right) return;
00100    const char *comma = strstr(left,",");
00101    if (!comma || comma > right) {
00102       //may be first bracket was a dimension specifier
00103       left = strstr(right,"[");
00104       if (!left) return;
00105       right = strstr(left,"]");
00106       if (!right) return;
00107       comma = strstr(left,",");
00108       if (!comma || comma >right) return;
00109    }
00110    //search if nbits is specified
00111    const char *comma2 = 0;
00112    if (comma) comma2 = strstr(comma+1,",");
00113    if (comma2 > right) comma2 = 0;
00114    Int_t nbits = 32;
00115    if (comma2) {
00116       TString sbits(comma2+1,right-comma2-1);
00117       sscanf(sbits.Data(),"%d",&nbits);
00118       if (nbits < 2 || nbits > 32) {
00119          ::Error("GetRange","Illegal specification for the number of bits; %d. reset to 32.",nbits);
00120          nbits = 32;
00121       }
00122       right = comma2;
00123    }
00124    TString range(left+1,right-left-1);
00125    TString sxmin(left+1,comma-left-1);
00126    sxmin.ToLower();
00127    sxmin.ReplaceAll(" ","");
00128    if (sxmin.Contains("pi")) {
00129       if      (sxmin.Contains("2pi"))   xmin = 2*kPi;
00130       else if (sxmin.Contains("2*pi"))  xmin = 2*kPi;
00131       else if (sxmin.Contains("twopi")) xmin = 2*kPi;
00132       else if (sxmin.Contains("pi/2"))  xmin = kPi/2;
00133       else if (sxmin.Contains("pi/4"))  xmin = kPi/4;
00134       else if (sxmin.Contains("pi"))    xmin = kPi;
00135       if (sxmin.Contains("-"))          xmin = -xmin;
00136    } else {
00137       sscanf(sxmin.Data(),"%lg",&xmin);
00138    }
00139    TString sxmax(comma+1,right-comma-1);
00140    sxmax.ToLower();
00141    sxmax.ReplaceAll(" ","");
00142    if (sxmax.Contains("pi")) {
00143       if      (sxmax.Contains("2pi"))   xmax = 2*kPi;
00144       else if (sxmax.Contains("2*pi"))  xmax = 2*kPi;
00145       else if (sxmax.Contains("twopi")) xmax = 2*kPi;
00146       else if (sxmax.Contains("pi/2"))  xmax = kPi/2;
00147       else if (sxmax.Contains("pi/4"))  xmax = kPi/4;
00148       else if (sxmax.Contains("pi"))    xmax = kPi;
00149       if (sxmax.Contains("-"))          xmax = -xmax;
00150    } else {
00151       sscanf(sxmax.Data(),"%lg",&xmax);
00152    }
00153    UInt_t bigint;
00154    if (nbits < 32)  bigint = 1<<nbits;
00155    else             bigint = 0xffffffff;
00156    if (xmin < xmax) factor = bigint/(xmax-xmin);
00157    if (xmin >= xmax && nbits <15) xmin = nbits+0.1;
00158 }
00159 
00160 ClassImp(TStreamerElement)
00161 
00162 //______________________________________________________________________________
00163 TStreamerElement::TStreamerElement()
00164 {
00165    // Default ctor.
00166 
00167    fType        = 0;
00168    fSize        = 0;
00169    fNewType     = 0;
00170    fArrayDim    = 0;
00171    fArrayLength = 0;
00172    fStreamer    = 0;
00173    fOffset      = 0;
00174    fClassObject = (TClass*)(-1);
00175    fNewClass    = 0;
00176    fTObjectOffset = 0;
00177    fFactor      = 0;
00178    fXmin        = 0;
00179    fXmax        = 0;
00180    for (Int_t i=0;i<5;i++) fMaxIndex[i] = 0;
00181 }
00182 
00183 //______________________________________________________________________________
00184 TStreamerElement::TStreamerElement(const char *name, const char *title, Int_t offset, Int_t dtype, const char *typeName)
00185         : TNamed(name,title)
00186 {
00187    // Create a TStreamerElement object.
00188 
00189    fOffset      = offset;
00190    fType        = dtype;
00191    fSize        = 0;
00192    fNewType     = fType;
00193    fArrayDim    = 0;
00194    fArrayLength = 0;
00195    fTypeName    = TClassEdit::ResolveTypedef(typeName);
00196    fStreamer    = 0;
00197    fClassObject = (TClass*)(-1);
00198    fNewClass    = 0;
00199    fTObjectOffset = 0;
00200    fFactor      = 0;
00201    fXmin        = 0;
00202    fXmax        = 0;
00203    for (Int_t i=0;i<5;i++) fMaxIndex[i] = 0;
00204    if (fTypeName == "Float16_t" || fTypeName == "Float16_t*") {
00205       GetRange(title,fXmin,fXmax,fFactor);
00206       if (fFactor > 0 || fXmin > 0) SetBit(kHasRange);
00207    }
00208    if (fTypeName == "Double32_t" || fTypeName == "Double32_t*") {
00209       GetRange(title,fXmin,fXmax,fFactor);
00210       if (fFactor > 0 || fXmin > 0) SetBit(kHasRange);
00211    }
00212 }
00213 
00214 //______________________________________________________________________________
00215 TStreamerElement::~TStreamerElement()
00216 {
00217    // TStreamerElement dtor.
00218 }
00219 
00220 
00221 //______________________________________________________________________________
00222 Bool_t TStreamerElement::CannotSplit() const
00223 {
00224    // Returns true if the element cannot be split, false otherwise.
00225    // An element cannot be split if the corresponding class member has
00226    // the special characters "||" as the first characters in the
00227    // comment field.
00228 
00229    if (strspn(GetTitle(),"||") == 2) return kTRUE;
00230    TClass *cl = GetClassPointer();
00231    if (!cl) return kFALSE;  //basic type
00232 
00233    switch(fType) {
00234       case TVirtualStreamerInfo::kAny    +TVirtualStreamerInfo::kOffsetL:
00235       case TVirtualStreamerInfo::kObject +TVirtualStreamerInfo::kOffsetL:
00236       case TVirtualStreamerInfo::kTObject+TVirtualStreamerInfo::kOffsetL:
00237       case TVirtualStreamerInfo::kTString+TVirtualStreamerInfo::kOffsetL:
00238       case TVirtualStreamerInfo::kTNamed +TVirtualStreamerInfo::kOffsetL:
00239          return kTRUE;
00240    }
00241 
00242    if ( !cl->CanSplit() ) return kTRUE;
00243 
00244    return kFALSE;
00245 }
00246 
00247 //______________________________________________________________________________
00248 TClass *TStreamerElement::GetClassPointer() const
00249 {
00250    // Returns a pointer to the TClass of this element.
00251 
00252    if (fClassObject!=(TClass*)(-1)) return fClassObject;
00253    TString className = fTypeName.Strip(TString::kTrailing, '*');
00254    if (className.Index("const ")==0) className.Remove(0,6);
00255    ((TStreamerElement*)this)->fClassObject = TClass::GetClass(className);
00256    return fClassObject;
00257 }
00258 
00259 //______________________________________________________________________________
00260 Int_t TStreamerElement::GetExecID() const
00261 {
00262    // Returns the TExec id for the EXEC instruction in the comment field
00263    // of a TRef data member.
00264 
00265    //check if element is a TRef or TRefArray
00266    if (strncmp(fTypeName.Data(),"TRef",4) != 0) return 0;
00267 
00268    //if the UniqueID of this element has already been set, we assume
00269    //that it contains the exec id of a TRef object.
00270    if (GetUniqueID()) return GetUniqueID();
00271 
00272    //check if an Exec is specified in the comment field
00273    char *action = (char*)strstr(GetTitle(),"EXEC:");
00274    if (!action) return 0;
00275    Int_t nch = strlen(action)+1;
00276    char *caction = new char[nch];
00277    strlcpy(caction,action+5,nch);
00278    char *blank = (char*)strchr(caction,' ');
00279    if (blank) *blank = 0;
00280    //we have found the Exec name in the comment
00281    //we register this Exec to the list of Execs.
00282    Int_t index = TRef::AddExec(caction);
00283    delete [] caction;
00284    //we save the Exec index as the uniqueid of this STreamerElement
00285    const_cast<TStreamerElement*>(this)->SetUniqueID(index+1);
00286    return index+1;
00287 }
00288 
00289 //______________________________________________________________________________
00290 const char *TStreamerElement::GetFullName() const
00291 {
00292    // Return element name including dimensions, if any
00293    // Note that this function stores the name into a static array.
00294    // You should copy the result.
00295 
00296    static TString name(kMaxLen);
00297    char cdim[20];
00298    name = GetName();
00299    for (Int_t i=0;i<fArrayDim;i++) {
00300       snprintf(cdim,19,"[%d]",fMaxIndex[i]);
00301       name += cdim;
00302    }
00303    return name;
00304 }
00305 
00306 //______________________________________________________________________________
00307 Int_t TStreamerElement::GetSize() const
00308 {
00309    // Returns size of this element in bytes.
00310 
00311    return fSize;
00312 }
00313 
00314 //______________________________________________________________________________
00315 TMemberStreamer *TStreamerElement::GetStreamer() const
00316 {
00317    // Return the local streamer object.
00318 
00319    return fStreamer;
00320 }
00321 
00322 //______________________________________________________________________________
00323 const char *TStreamerElement::GetTypeNameBasic() const
00324 {
00325    // Return type name of this element
00326    // in case the type name is not a standard basic type, return
00327    // the basic type name known to CINT.
00328 
00329    TDataType *dt = gROOT->GetType(fTypeName.Data());
00330    if (fType < 1 || fType > 55) return fTypeName.Data();
00331    if (dt && dt->GetType() > 0) return fTypeName.Data();
00332    Int_t dtype = fType%20;
00333    return TDataType::GetTypeName((EDataType)dtype);
00334 }
00335 
00336 //______________________________________________________________________________
00337 void TStreamerElement::Init(TObject *)
00338 {
00339    // Initliaze the element.
00340 
00341    fClassObject = GetClassPointer();
00342    if (fClassObject && fClassObject->InheritsFrom(TObject::Class())) {
00343       fTObjectOffset = fClassObject->GetBaseClassOffset(TObject::Class());
00344    }
00345 }
00346 
00347 //______________________________________________________________________________
00348 Bool_t TStreamerElement::IsOldFormat(const char *newTypeName)
00349 {
00350    // The early 3.00/00 and 3.01/01 versions used to store
00351    // dm->GetTypeName instead of dm->GetFullTypename
00352    // if this case is detected, the element type name is modified.
00353 
00354    //if (!IsaPointer()) return kFALSE;
00355    if (!strstr(newTypeName,fTypeName.Data())) return kFALSE;
00356    //if (!strstr(fTypeName.Data(),newTypeName)) return kFALSE;
00357    fTypeName = newTypeName;
00358    return kTRUE;
00359 }
00360 
00361 //______________________________________________________________________________
00362 Bool_t TStreamerElement::IsBase() const
00363 {
00364    // Return kTRUE if the element represent a base class.
00365 
00366    return kFALSE;
00367 }
00368 
00369 //______________________________________________________________________________
00370 void TStreamerElement::ls(Option_t *) const
00371 {
00372    // Print the content of the element.
00373 
00374    TString temp(GetTypeName());
00375    if (IsaPointer() && !fTypeName.Contains("*")) temp += "*";
00376    printf("  %-14s %-15s offset=%3d type=%2d %s%-20s\n",
00377       temp.Data(),GetFullName(),fOffset,fType,TestBit(kCache)?"(cached) ":"",
00378       GetTitle());
00379 }
00380 
00381 //______________________________________________________________________________
00382 void TStreamerElement::SetArrayDim(Int_t dim)
00383 {
00384    // Set number of array dimensions.
00385 
00386    fArrayDim = dim;
00387    if (dim) fType += TVirtualStreamerInfo::kOffsetL;
00388    fNewType = fType;
00389 }
00390 
00391 //______________________________________________________________________________
00392 void TStreamerElement::SetMaxIndex(Int_t dim, Int_t max)
00393 {
00394    //set maximum index for array with dimension dim
00395 
00396    if (dim < 0 || dim > 4) return;
00397    fMaxIndex[dim] = max;
00398    if (fArrayLength == 0)  fArrayLength  = max;
00399    else                    fArrayLength *= max;
00400 }
00401 
00402 //______________________________________________________________________________
00403 void TStreamerElement::SetStreamer(TMemberStreamer *streamer)
00404 {
00405    //set pointer to Streamer function for this element
00406 
00407    fStreamer = streamer;
00408 }
00409 
00410 //______________________________________________________________________________
00411 void TStreamerElement::Streamer(TBuffer &R__b)
00412 {
00413    // Stream an object of class TStreamerElement.
00414 
00415    UInt_t R__s, R__c;
00416    if (R__b.IsReading()) {
00417       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00418       //NOTE that when reading, one cannot use Class()->ReadBuffer
00419       // TBuffer::Class methods used for reading streamerinfos from SQL database
00420       // Any changes of class structure should be reflected by them starting from version 4
00421       
00422       R__b.ClassBegin(TStreamerElement::Class(), R__v);
00423       R__b.ClassMember("TNamed");
00424       TNamed::Streamer(R__b);
00425       R__b.ClassMember("fType","Int_t");
00426       R__b >> fType;
00427       R__b.ClassMember("fSize","Int_t");
00428       R__b >> fSize;
00429       R__b.ClassMember("fArrayLength","Int_t");
00430       R__b >> fArrayLength;
00431       R__b.ClassMember("fArrayDim","Int_t");
00432       R__b >> fArrayDim;
00433       R__b.ClassMember("fMaxIndex","Int_t", 5);
00434       if (R__v == 1) R__b.ReadStaticArray(fMaxIndex);
00435       else           R__b.ReadFastArray(fMaxIndex,5);
00436       R__b.ClassMember("fTypeName","TString");
00437       fTypeName.Streamer(R__b);
00438       if (fType==11&&(fTypeName=="Bool_t"||fTypeName=="bool")) fType = 18;
00439       if (R__v > 1) {
00440          SetUniqueID(0);
00441          //check if element is a TRef or TRefArray
00442          GetExecID();
00443       }
00444       if (R__v <= 2 && this->IsA()==TStreamerBasicType::Class()) {
00445          // In TStreamerElement v2, fSize was holding the size of
00446          // the underlying data type.  In later version it contains 
00447          // the full length of the data member.
00448          TDataType *type = gROOT->GetType(GetTypeName());
00449          if (type && fArrayLength) fSize = fArrayLength * type->Size();
00450       }
00451       if (R__v == 3) {
00452          R__b >> fXmin;
00453          R__b >> fXmax;
00454          R__b >> fFactor;
00455          if (fFactor > 0) SetBit(kHasRange);
00456       }
00457       if (R__v > 3) {
00458          if (TestBit(kHasRange)) GetRange(GetTitle(),fXmin,fXmax,fFactor);
00459       }
00460       //R__b.CheckByteCount(R__s, R__c, TStreamerElement::IsA());
00461       R__b.ClassEnd(TStreamerElement::Class());
00462       R__b.SetBufferOffset(R__s+R__c+sizeof(UInt_t));
00463       
00464       ResetBit(TStreamerElement::kCache);
00465    } else {
00466       R__b.WriteClassBuffer(TStreamerElement::Class(),this);
00467    }
00468 }
00469 
00470 //______________________________________________________________________________
00471 void TStreamerElement::Update(const TClass *oldClass, TClass *newClass)
00472 {
00473    //function called by the TClass constructor when replacing an emulated class
00474    //by the real class
00475 
00476    if (fClassObject == oldClass) {
00477       fClassObject = newClass;
00478       if (fClassObject && fClassObject->InheritsFrom(TObject::Class())) {
00479          fTObjectOffset = fClassObject->GetBaseClassOffset(TObject::Class());
00480       }
00481    } else if (fClassObject==0) {
00482       // Well since some emulated class is replaced by a real class, we can
00483       // assume a new library has been loaded.  If this is the case, we should
00484       // check whether the class now exist (this would be the case for example
00485       // for reading STL containers).
00486       fClassObject = (TClass*)-1;
00487       GetClassPointer(); //force fClassObject
00488       if (fClassObject && fClassObject->InheritsFrom(TObject::Class())) {
00489          fTObjectOffset = fClassObject->GetBaseClassOffset(TObject::Class());
00490       }
00491    }
00492 }
00493 
00494 //______________________________________________________________________________
00495 
00496 //////////////////////////////////////////////////////////////////////////
00497 //                                                                      //
00498 // TStreamerBase implement the streamer of the base class               //
00499 //                                                                      //
00500 //////////////////////////////////////////////////////////////////////////
00501 
00502 ClassImp(TStreamerBase)
00503 
00504 //______________________________________________________________________________
00505 TStreamerBase::TStreamerBase() : fStreamerFunc(0)
00506 {
00507    // Default ctor.
00508 
00509    fBaseClass = (TClass*)(-1);
00510    fBaseVersion = 0;
00511    fNewBaseClass = 0;
00512 }
00513 
00514 //______________________________________________________________________________
00515 TStreamerBase::TStreamerBase(const char *name, const char *title, Int_t offset)
00516         : TStreamerElement(name,title,offset,TVirtualStreamerInfo::kBase,"BASE"),fStreamerFunc(0)
00517 {
00518    // Create a TStreamerBase object.
00519 
00520    if (strcmp(name,"TObject") == 0) fType = TVirtualStreamerInfo::kTObject;
00521    if (strcmp(name,"TNamed")  == 0) fType = TVirtualStreamerInfo::kTNamed;
00522    fNewType = fType;
00523    fBaseClass = TClass::GetClass(GetName());
00524    fBaseVersion = fBaseClass->GetClassVersion();
00525    fNewBaseClass = 0;
00526    Init();
00527 }
00528 
00529 //______________________________________________________________________________
00530 TStreamerBase::~TStreamerBase()
00531 {
00532    // TStreamerBase dtor
00533 }
00534 
00535 //______________________________________________________________________________
00536 TClass *TStreamerBase::GetClassPointer() const
00537 {
00538    // Returns a pointer to the TClass of this element.
00539    if (fBaseClass!=(TClass*)(-1)) return fBaseClass;
00540    ((TStreamerBase*)this)->fBaseClass = TClass::GetClass(GetName());
00541    return fBaseClass;
00542 }
00543 
00544 //______________________________________________________________________________
00545 Int_t TStreamerBase::GetSize() const
00546 {
00547    // Returns size of baseclass in bytes.
00548 
00549    TClass *cl = GetClassPointer();
00550    if (cl) return cl->Size();
00551    return 0;
00552 }
00553 
00554 //______________________________________________________________________________
00555 void TStreamerBase::Init(TObject *)
00556 {
00557    // Setup the element.
00558 
00559    if (fType == TVirtualStreamerInfo::kTObject || fType == TVirtualStreamerInfo::kTNamed) return;
00560    fBaseClass = TClass::GetClass(GetName());
00561    if (!fBaseClass) return;
00562    if (!fBaseClass->GetMethodAny("StreamerNVirtual")) return;
00563    fStreamerFunc = fBaseClass->GetStreamerFunc();
00564 }
00565 
00566 //______________________________________________________________________________
00567 Bool_t TStreamerBase::IsBase() const
00568 {
00569    // Return kTRUE if the element represent a base class.
00570 
00571    return kTRUE;
00572 }
00573 
00574 //______________________________________________________________________________
00575 const char *TStreamerBase::GetInclude() const
00576 {
00577    // Return the proper include for this element.
00578 
00579    if (GetClassPointer() && fBaseClass->GetClassInfo()) {
00580       gIncludeName.Form("\"%s\"",fBaseClass->GetDeclFileName());
00581    } else {
00582       std::string shortname( TClassEdit::ShortType( GetName(), 1 ) );
00583       gIncludeName.Form("\"%s.h\"",shortname.c_str());
00584    }
00585    return gIncludeName;
00586 }
00587 
00588 //______________________________________________________________________________
00589 void TStreamerBase::ls(Option_t *) const
00590 {
00591    // Print the content of the element.
00592 
00593    printf("  %-14s %-15s offset=%3d type=%2d %s%-20s\n",GetFullName(),GetTypeName(),fOffset,fType,TestBit(kCache)?"(cached) ":"",GetTitle());
00594 }
00595 
00596 //______________________________________________________________________________
00597 Int_t TStreamerBase::ReadBuffer (TBuffer &b, char *pointer)
00598 {
00599    // Read the content of the buffer.
00600 
00601    if (fStreamerFunc) {
00602       // We have a custom Streamer member function, we must use it.
00603       fStreamerFunc(b,pointer+fOffset);
00604    } else {
00605       // We don't have a custom Streamer member function. That still doesn't mean
00606       // that there is no streamer - it could be an external one:
00607       // If the old base class has an adopted streamer we take that
00608       // one instead of the new base class:
00609       if( fNewBaseClass ) {
00610          TClassStreamer* extstrm = fNewBaseClass->GetStreamer();                  
00611          if (extstrm) {
00612             // The new base class has an adopted streamer:
00613             extstrm->SetOnFileClass(fBaseClass);
00614             (*extstrm)(b, pointer);
00615          } else {
00616             b.ReadClassBuffer( fNewBaseClass, pointer+fOffset, fBaseClass ); 
00617          }
00618       } else {
00619          TClassStreamer* extstrm = fBaseClass->GetStreamer();         
00620          if (extstrm) {
00621             // The class has an adopted streamer:
00622             (*extstrm)(b, pointer);
00623          } else {
00624             b.ReadClassBuffer( fBaseClass, pointer+fOffset );
00625          }
00626       }
00627    }
00628    return 0;
00629 }
00630 
00631 //______________________________________________________________________________
00632 void TStreamerBase::Streamer(TBuffer &R__b)
00633 {
00634    // Stream an object of class TStreamerBase.
00635 
00636    UInt_t R__s, R__c;
00637    if (R__b.IsReading()) {
00638       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00639       
00640       R__b.ClassBegin(TStreamerBase::Class(), R__v);
00641       
00642       R__b.ClassMember("TStreamerElement");
00643       TStreamerElement::Streamer(R__b);
00644       // If the class owning the TStreamerElement and the base class are not
00645       // loaded, on the file their streamer info might be in the following 
00646       // order (derived class,base class) and hence the base class is not
00647       // yet emulated.
00648       fBaseClass = (TClass*)-1;
00649       fNewBaseClass = 0;
00650       if (R__v > 2) {
00651          R__b.ClassMember("fBaseVersion","Int_t");
00652          R__b >> fBaseVersion;
00653       } else {
00654          // could have been: fBaseVersion = GetClassPointer()->GetClassVersion();
00655          fBaseClass = TClass::GetClass(GetName());         
00656          fBaseVersion = fBaseClass->GetClassVersion();
00657       }
00658       R__b.ClassEnd(TStreamerBase::Class());
00659       R__b.SetBufferOffset(R__s+R__c+sizeof(UInt_t));
00660    } else {
00661       R__b.WriteClassBuffer(TStreamerBase::Class(),this);
00662    }
00663 }
00664 
00665 //______________________________________________________________________________
00666 void TStreamerBase::Update(const TClass *oldClass, TClass *newClass)
00667 {
00668    //Function called by the TClass constructor when replacing an emulated class
00669    //by the real class.
00670 
00671    if (fClassObject == oldClass) fClassObject = newClass;
00672    else if (fClassObject == 0) {
00673       fClassObject = (TClass*)-1;
00674       GetClassPointer(); //force fClassObject
00675    }
00676    if (fBaseClass   == oldClass) fBaseClass   = newClass;
00677    else if (fBaseClass == 0 ) {
00678       fBaseClass = (TClass*)-1;
00679       GetClassPointer(); //force fClassObject
00680    }
00681    if (fClassObject != (TClass*)-1 &&
00682        fClassObject && fClassObject->InheritsFrom(TObject::Class())) {
00683       fTObjectOffset = fClassObject->GetBaseClassOffset(TObject::Class());
00684    }
00685    if (fBaseClass && fBaseClass != (TClass*)-1) {
00686       fStreamerFunc = fBaseClass->GetStreamerFunc();
00687    } else {
00688       fStreamerFunc = 0;
00689    }
00690 }
00691 
00692 //______________________________________________________________________________
00693 Int_t TStreamerBase::WriteBuffer (TBuffer &b, char *pointer)
00694 {
00695    // Write the base class into the buffer.
00696 
00697    if (fStreamerFunc) {
00698       // We have a custom Streamer member function, we must use it.
00699       fStreamerFunc(b,pointer+fOffset);      
00700    } else {
00701       // We don't have a custom Streamer member function. That still doesn't mean
00702       // that there is no streamer - it could be an external one:
00703       // If the old base class has an adopted streamer we take that
00704       // one instead of the new base class:
00705       if (fNewBaseClass) {
00706          TClassStreamer* extstrm = fNewBaseClass->GetStreamer();
00707          if (extstrm) {
00708             // The new base class has an adopted streamer:
00709             extstrm->SetOnFileClass(fBaseClass);
00710             (*extstrm)(b, pointer);
00711             return 0;
00712          } else {
00713             fNewBaseClass->WriteBuffer(b,pointer+fOffset);
00714             return 0;
00715          }
00716       } else {
00717          TClassStreamer* extstrm = fBaseClass->GetStreamer();
00718          if (extstrm) {
00719             (*extstrm)(b, pointer);
00720             return 0;
00721          } else {
00722             fBaseClass->WriteBuffer(b,pointer+fOffset);
00723             return 0;
00724          }
00725       }
00726    }
00727    return 0;
00728 }
00729 
00730 //______________________________________________________________________________
00731 
00732 //////////////////////////////////////////////////////////////////////////
00733 //                                                                      //
00734 // TStreamerBasicPointer implements the streamering of pointer to       //
00735 // fundamental types.                                                   //
00736 //                                                                      //
00737 //////////////////////////////////////////////////////////////////////////
00738 
00739 ClassImp(TStreamerBasicPointer)
00740 
00741 //______________________________________________________________________________
00742 TStreamerBasicPointer::TStreamerBasicPointer() : fCountVersion(0),fCountName(),fCountClass(),fCounter(0)
00743 {
00744    // Default ctor.
00745    fCounter = 0;
00746 }
00747 
00748 //______________________________________________________________________________
00749 TStreamerBasicPointer::TStreamerBasicPointer(const char *name, const char *title, Int_t offset, Int_t dtype, const char *countName, const char *countClass, Int_t countVersion, const char *typeName)
00750    : TStreamerElement(name,title,offset,dtype,typeName)
00751 {
00752    // Create a TStreamerBasicPointer object.
00753 
00754    fType += TVirtualStreamerInfo::kOffsetP;
00755    fCountName    = countName;
00756    fCountClass   = countClass;
00757    fCountVersion = countVersion;  //currently unused
00758    Init();
00759 //   printf("BasicPointer Init:%s, countName=%s, countClass=%s, countVersion=%d, fCounter=%x\n",
00760 //      name,countName,countClass,countVersion,fCounter);
00761 }
00762 
00763 //______________________________________________________________________________
00764 TStreamerBasicPointer::~TStreamerBasicPointer()
00765 {
00766    // TStreamerBasicPointer dtor.
00767 }
00768 
00769 //______________________________________________________________________________
00770 ULong_t TStreamerBasicPointer::GetMethod() const
00771 {
00772    // return offset of counter
00773 
00774    if (!fCounter) ((TStreamerBasicPointer*)this)->Init();
00775    if (!fCounter) return 0;
00776    return (ULong_t)fCounter->GetOffset();
00777 }
00778 
00779 //______________________________________________________________________________
00780 Int_t TStreamerBasicPointer::GetSize() const
00781 {
00782    // Returns size of basicpointer in bytes.
00783 
00784    if (fArrayLength) return fArrayLength*sizeof(void *);
00785    return sizeof(void *);
00786 }
00787 
00788 //______________________________________________________________________________
00789 void TStreamerBasicPointer::Init(TObject *directive)
00790 {
00791    // Setup the element.
00792    // If directive is a StreamerInfo and it correspond to the 
00793    // same class a 'countClass' the streamerInfo is used instead of the current StreamerInfo of the TClass
00794    // for 'countClass'.
00795    
00796    fCounter = InitCounter( fCountClass, fCountName, directive );
00797 }
00798 
00799 //______________________________________________________________________________
00800 void TStreamerBasicPointer::SetArrayDim(Int_t dim)
00801 {
00802    // Set number of array dimensions.
00803 
00804    fArrayDim = dim;
00805    //if (dim) fType += TVirtualStreamerInfo::kOffsetL;
00806    fNewType = fType;
00807 }
00808 
00809 //______________________________________________________________________________
00810 void TStreamerBasicPointer::Streamer(TBuffer &R__b)
00811 {
00812    // Stream an object of class TStreamerBasicPointer.
00813 
00814    UInt_t R__s, R__c;
00815    if (R__b.IsReading()) {
00816       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00817       if (R__v > 1) {
00818          R__b.ReadClassBuffer(TStreamerBasicPointer::Class(), this, R__v, R__s, R__c);
00819          //Init();
00820          //fCounter = InitCounter( fCountClass, fCountName );
00821          return;
00822       }
00823       //====process old versions before automatic schema evolution
00824       TStreamerElement::Streamer(R__b);
00825       R__b >> fCountVersion;
00826       fCountName.Streamer(R__b);
00827       fCountClass.Streamer(R__b);
00828       R__b.SetBufferOffset(R__s+R__c+sizeof(UInt_t));
00829    } else {
00830       R__b.WriteClassBuffer(TStreamerBasicPointer::Class(),this);
00831    }
00832 }
00833 
00834 
00835 //______________________________________________________________________________
00836 
00837 //////////////////////////////////////////////////////////////////////////
00838 //                                                                      //
00839 // TStreamerLoop implement streaming of a few construct that require    //
00840 // looping over the data member and are not convered by other case      //
00841 // (most deprecated).                                                   //
00842 //                                                                      //
00843 //////////////////////////////////////////////////////////////////////////
00844 
00845 ClassImp(TStreamerLoop)
00846 
00847 //______________________________________________________________________________
00848 TStreamerLoop::TStreamerLoop() : fCountVersion(0),fCountName(),fCountClass(),fCounter(0)
00849 {
00850    // Default ctor.
00851 
00852 }
00853 
00854 //______________________________________________________________________________
00855 TStreamerLoop::TStreamerLoop(const char *name, const char *title, Int_t offset, const char *countName, const char *countClass, Int_t countVersion, const char *typeName)
00856         : TStreamerElement(name,title,offset,TVirtualStreamerInfo::kStreamLoop,typeName)
00857 {
00858    // Create a TStreamerLoop object.
00859 
00860    fCountName    = countName;
00861    fCountClass   = countClass;
00862    fCountVersion = countVersion;  //currently unused
00863    Init();
00864 }
00865 
00866 //______________________________________________________________________________
00867 TStreamerLoop::~TStreamerLoop()
00868 {
00869    // TStreamerLoop dtor.
00870 }
00871 
00872 //______________________________________________________________________________
00873 ULong_t TStreamerLoop::GetMethod() const
00874 {
00875    // return address of counter
00876 
00877    //if (!fCounter) {
00878    //   Init();
00879    //   if (!fCounter) return 0;
00880    //}
00881    if (!fCounter) return 0;
00882    return (ULong_t)fCounter->GetOffset();
00883 }
00884 
00885 //______________________________________________________________________________
00886 Int_t TStreamerLoop::GetSize() const
00887 {
00888    // Returns size of counter in bytes.
00889 
00890    if (fArrayLength) return fArrayLength*sizeof(Int_t);
00891    return sizeof(Int_t);
00892 }
00893 
00894 //______________________________________________________________________________
00895 void TStreamerLoop::Init(TObject *directive)
00896 {
00897    // Setup the element.
00898    // If directive is a StreamerInfo and it correspond to the 
00899    // same class a 'countClass' the streamerInfo is used instead of the current StreamerInfo of the TClass
00900    // for 'countClass'.
00901 
00902    fCounter = InitCounter( fCountClass, fCountName, directive );
00903 }
00904 
00905 //______________________________________________________________________________
00906 const char *TStreamerLoop::GetInclude() const
00907 {
00908    // Return the proper include for this element.
00909 
00910    gIncludeName.Form("<%s>","TString.h"); //to be generalized
00911    return gIncludeName;
00912 }
00913 
00914 //______________________________________________________________________________
00915 void TStreamerLoop::Streamer(TBuffer &R__b)
00916 {
00917    // Stream an object of class TStreamerLoop.
00918 
00919    UInt_t R__s, R__c;
00920    if (R__b.IsReading()) {
00921       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00922       if (R__v > 1) {
00923          R__b.ReadClassBuffer(TStreamerLoop::Class(), this, R__v, R__s, R__c);
00924          //Init();
00925          return;
00926       }
00927       //====process old versions before automatic schema evolution
00928       TStreamerElement::Streamer(R__b);
00929       R__b >> fCountVersion;
00930       fCountName.Streamer(R__b);
00931       fCountClass.Streamer(R__b);
00932       R__b.SetBufferOffset(R__s+R__c+sizeof(UInt_t));
00933    } else {
00934       R__b.WriteClassBuffer(TStreamerLoop::Class(),this);
00935    }
00936 }
00937 
00938 
00939 //______________________________________________________________________________
00940 
00941 //////////////////////////////////////////////////////////////////////////
00942 //                                                                      //
00943 // TStreamerBasicType implement streaming of fundamental types (int,    //
00944 // float, etc.).                                                        //
00945 //                                                                      //
00946 //////////////////////////////////////////////////////////////////////////
00947 
00948 ClassImp(TStreamerBasicType)
00949 
00950 //______________________________________________________________________________
00951 TStreamerBasicType::TStreamerBasicType() : fCounter(0)
00952 {
00953    // Default ctor.
00954 
00955 }
00956 
00957 //______________________________________________________________________________
00958 TStreamerBasicType::TStreamerBasicType(const char *name, const char *title, Int_t offset, Int_t dtype, const char *typeName)
00959         : TStreamerElement(name,title,offset,dtype,typeName),fCounter(0)
00960 {
00961    // Create a TStreamerBasicType object.
00962 
00963 }
00964 
00965 //______________________________________________________________________________
00966 TStreamerBasicType::~TStreamerBasicType()
00967 {
00968    // TStreamerBasicType dtor.
00969 }
00970 
00971 //______________________________________________________________________________
00972 ULong_t TStreamerBasicType::GetMethod() const
00973 {
00974    // return address of counter
00975 
00976    if (fType ==  TVirtualStreamerInfo::kCounter ||
00977        fType == (TVirtualStreamerInfo::kCounter+TVirtualStreamerInfo::kSkip)) return (ULong_t)&fCounter;
00978    return 0;
00979 }
00980 
00981 //______________________________________________________________________________
00982 Int_t TStreamerBasicType::GetSize() const
00983 {
00984    // Returns size of this element in bytes.
00985 
00986    return fSize;
00987 }
00988 
00989 //______________________________________________________________________________
00990 void TStreamerBasicType::Streamer(TBuffer &R__b)
00991 {
00992    // Stream an object of class TStreamerBasicType.
00993 
00994    UInt_t R__s, R__c;
00995    if (R__b.IsReading()) {
00996       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
00997       if (R__v > 1) {
00998          R__b.ReadClassBuffer(TStreamerBasicType::Class(), this, R__v, R__s, R__c);
00999       } else {
01000          //====process old versions before automatic schema evolution
01001          TStreamerElement::Streamer(R__b);
01002          R__b.CheckByteCount(R__s, R__c, TStreamerBasicType::IsA());
01003       }
01004       switch(fType) {
01005          // basic types
01006          case kBool_t:     fSize = sizeof(bool);      break;
01007          case kShort_t:    fSize = sizeof(Short_t);   break;
01008          case kInt_t:      fSize = sizeof(Int_t);     break;
01009          case kLong_t:     fSize = sizeof(Long_t);    break; 
01010          case kLong64_t:   fSize = sizeof(Long64_t);  break;
01011          case kFloat_t:    fSize = sizeof(Float_t);   break;
01012          case kFloat16_t:  fSize = sizeof(Float_t);   break;
01013          case kDouble_t:   fSize = sizeof(Double_t);  break;
01014          case kDouble32_t: fSize = sizeof(Double_t);  break;
01015          case kUChar_t:    fSize = sizeof(UChar_t);   break;
01016          case kUShort_t:   fSize = sizeof(UShort_t);  break;
01017          case kUInt_t:     fSize = sizeof(UInt_t);    break;
01018          case kULong_t:    fSize = sizeof(ULong_t);   break;
01019          case kULong64_t:  fSize = sizeof(ULong64_t); break;
01020          case kBits:       fSize = sizeof(UInt_t);    break;
01021          case kCounter:    fSize = sizeof(Int_t);     break;
01022          case kChar_t:     fSize = sizeof(Char_t);    break;
01023          case kCharStar:   fSize = sizeof(Char_t*);   break;
01024          default:          return; // If we don't change the size let's not remultiply it.
01025       }
01026       if (fArrayLength) fSize *= GetArrayLength();
01027    } else {
01028       R__b.WriteClassBuffer(TStreamerBasicType::Class(),this);
01029    }
01030 }
01031 
01032 
01033 
01034 //______________________________________________________________________________
01035 
01036 //////////////////////////////////////////////////////////////////////////
01037 //                                                                      //
01038 // TStreamerObject implements streaming of embedded objects whose type  //
01039 // inherits from TObject.                                               //
01040 //                                                                      //
01041 //////////////////////////////////////////////////////////////////////////
01042 
01043 ClassImp(TStreamerObject)
01044 
01045 //______________________________________________________________________________
01046 TStreamerObject::TStreamerObject()
01047 {
01048    // Default ctor.
01049 
01050 }
01051 
01052 //______________________________________________________________________________
01053 TStreamerObject::TStreamerObject(const char *name, const char *title, Int_t offset, const char *typeName)
01054         : TStreamerElement(name,title,offset,0,typeName)
01055 {
01056    // Create a TStreamerObject object.
01057 
01058    fType = TVirtualStreamerInfo::kObject;
01059    if (strcmp(typeName,"TObject") == 0) fType = TVirtualStreamerInfo::kTObject;
01060    if (strcmp(typeName,"TNamed")  == 0) fType = TVirtualStreamerInfo::kTNamed;
01061    fNewType = fType;
01062    Init();
01063 }
01064 
01065 //______________________________________________________________________________
01066 TStreamerObject::~TStreamerObject()
01067 {
01068    // TStreamerObject dtor.
01069 }
01070 
01071 //______________________________________________________________________________
01072 void TStreamerObject::Init(TObject *)
01073 {
01074    // Setup the element.
01075 
01076    fClassObject = GetClassPointer();
01077    if (fClassObject && fClassObject->InheritsFrom(TObject::Class())) {
01078       fTObjectOffset = fClassObject->GetBaseClassOffset(TObject::Class());
01079    }
01080 }
01081 
01082 //______________________________________________________________________________
01083 const char *TStreamerObject::GetInclude() const
01084 {
01085    // Return the proper include for this element.
01086 
01087    TClass *cl = GetClassPointer();
01088    if (cl && cl->GetClassInfo()) {
01089       gIncludeName.Form("\"%s\"",cl->GetDeclFileName());
01090    } else {
01091       std::string shortname( TClassEdit::ShortType( GetTypeName(), 1 ) );
01092       gIncludeName.Form("\"%s.h\"",shortname.c_str());
01093    }
01094    return gIncludeName;
01095 }
01096 
01097 //______________________________________________________________________________
01098 Int_t TStreamerObject::GetSize() const
01099 {
01100    // Returns size of object class in bytes.
01101 
01102    TClass *cl = GetClassPointer();
01103    Int_t classSize = 8;
01104    if (cl) classSize = cl->Size();
01105    if (fArrayLength) return fArrayLength*classSize;
01106    return classSize;
01107 }
01108 
01109 //______________________________________________________________________________
01110 void TStreamerObject::Streamer(TBuffer &R__b)
01111 {
01112    // Stream an object of class TStreamerObject.
01113 
01114    UInt_t R__s, R__c;
01115    if (R__b.IsReading()) {
01116       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01117       if (R__v > 1) {
01118          R__b.ReadClassBuffer(TStreamerObject::Class(), this, R__v, R__s, R__c);
01119          return;
01120       }
01121       //====process old versions before automatic schema evolution
01122       TStreamerElement::Streamer(R__b);
01123       R__b.CheckByteCount(R__s, R__c, TStreamerObject::IsA());
01124    } else {
01125       R__b.WriteClassBuffer(TStreamerObject::Class(),this);
01126    }
01127 }
01128 
01129 
01130 //______________________________________________________________________________
01131 
01132 //////////////////////////////////////////////////////////////////////////
01133 //                                                                      //
01134 // TStreamerObjectAny implement streaming of embedded object not        //
01135 // inheriting from TObject.                                             //
01136 //                                                                      //
01137 //////////////////////////////////////////////////////////////////////////
01138 
01139 ClassImp(TStreamerObjectAny)
01140 
01141 //______________________________________________________________________________
01142 TStreamerObjectAny::TStreamerObjectAny()
01143 {
01144    // Default ctor.
01145 
01146 }
01147 
01148 //______________________________________________________________________________
01149 TStreamerObjectAny::TStreamerObjectAny(const char *name, const char *title, Int_t offset, const char *typeName)
01150         : TStreamerElement(name,title,offset,TVirtualStreamerInfo::kAny,typeName)
01151 {
01152    // Create a TStreamerObjectAny object.
01153    Init();
01154 }
01155 
01156 //______________________________________________________________________________
01157 TStreamerObjectAny::~TStreamerObjectAny()
01158 {
01159    // TStreamerObjectAny dtor.
01160 }
01161 
01162 //______________________________________________________________________________
01163 void TStreamerObjectAny::Init(TObject *)
01164 {
01165    // Setup the element.
01166 
01167    fClassObject = GetClassPointer();
01168    if (fClassObject && fClassObject->InheritsFrom(TObject::Class())) {
01169       fTObjectOffset = fClassObject->GetBaseClassOffset(TObject::Class());
01170    }
01171 }
01172 
01173 //______________________________________________________________________________
01174 const char *TStreamerObjectAny::GetInclude() const
01175 {
01176    // Return the proper include for this element.
01177 
01178    TClass *cl = GetClassPointer();
01179    if (cl && cl->GetClassInfo()) {
01180       gIncludeName.Form("\"%s\"",cl->GetDeclFileName());
01181    } else {
01182       std::string shortname( TClassEdit::ShortType( GetTypeName(), 1 ) );
01183       gIncludeName.Form("\"%s.h\"",shortname.c_str());
01184    }
01185    return gIncludeName;
01186 }
01187 
01188 //______________________________________________________________________________
01189 Int_t TStreamerObjectAny::GetSize() const
01190 {
01191    // Returns size of anyclass in bytes.
01192 
01193    TClass *cl = GetClassPointer();
01194    Int_t classSize = 8;
01195    if (cl) classSize = cl->Size();
01196    if (fArrayLength) return fArrayLength*classSize;
01197    return classSize;
01198 }
01199 
01200 //______________________________________________________________________________
01201 void TStreamerObjectAny::Streamer(TBuffer &R__b)
01202 {
01203    // Stream an object of class TStreamerObjectAny.
01204 
01205    UInt_t R__s, R__c;
01206    if (R__b.IsReading()) {
01207       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01208       if (R__v > 1) {
01209          R__b.ReadClassBuffer(TStreamerObjectAny::Class(), this, R__v, R__s, R__c);
01210          return;
01211       }
01212       //====process old versions before automatic schema evolution
01213       TStreamerElement::Streamer(R__b);
01214       R__b.CheckByteCount(R__s, R__c, TStreamerObjectAny::IsA());
01215    } else {
01216       R__b.WriteClassBuffer(TStreamerObjectAny::Class(),this);
01217    }
01218 }
01219 
01220 
01221 
01222 //______________________________________________________________________________
01223 
01224 //////////////////////////////////////////////////////////////////////////
01225 //                                                                      //
01226 // TStreamerObjectPointer implements streaming of pointer to object     //
01227 // inheriting from TObject.                                             //
01228 //                                                                      //
01229 //////////////////////////////////////////////////////////////////////////
01230 
01231 ClassImp(TStreamerObjectPointer)
01232 
01233 //______________________________________________________________________________
01234 TStreamerObjectPointer::TStreamerObjectPointer()
01235 {
01236    // Default ctor.
01237 
01238 }
01239 
01240 //______________________________________________________________________________
01241 TStreamerObjectPointer::TStreamerObjectPointer(const char *name, const char *title,
01242                                                Int_t offset, const char *typeName)
01243    : TStreamerElement(name,title,offset,TVirtualStreamerInfo::kObjectP,typeName)
01244 {
01245    // Create a TStreamerObjectPointer object.
01246 
01247    if (strncmp(title,"->",2) == 0) fType = TVirtualStreamerInfo::kObjectp;
01248    fNewType = fType;
01249    Init();
01250 }
01251 
01252 //______________________________________________________________________________
01253 TStreamerObjectPointer::~TStreamerObjectPointer()
01254 {
01255    // TStreamerObjectPointer dtor.
01256 }
01257 
01258 //______________________________________________________________________________
01259 void TStreamerObjectPointer::Init(TObject *)
01260 {
01261    // Setup the element.
01262 
01263    fClassObject = GetClassPointer();
01264    if (fClassObject && fClassObject->InheritsFrom(TObject::Class())) {
01265       fTObjectOffset = fClassObject->GetBaseClassOffset(TObject::Class());
01266    }
01267 }
01268 
01269 //______________________________________________________________________________
01270 const char *TStreamerObjectPointer::GetInclude() const
01271 {
01272    // Return the proper include for this element.
01273 
01274    TClass *cl = GetClassPointer();
01275    if (cl && cl->GetClassInfo()) {
01276       gIncludeName.Form("\"%s\"",cl->GetDeclFileName());
01277    } else {
01278       std::string shortname( TClassEdit::ShortType( GetTypeName(), 1 ) );
01279       gIncludeName.Form("\"%s.h\"",shortname.c_str());
01280    }
01281 
01282    return gIncludeName;
01283 }
01284 
01285 //______________________________________________________________________________
01286 Int_t TStreamerObjectPointer::GetSize() const
01287 {
01288    // Returns size of objectpointer in bytes.
01289 
01290    if (fArrayLength) return fArrayLength*sizeof(void *);
01291    return sizeof(void *);
01292 }
01293 
01294 //______________________________________________________________________________
01295 void TStreamerObjectPointer::SetArrayDim(Int_t dim)
01296 {
01297    // Set number of array dimensions.
01298 
01299    fArrayDim = dim;
01300    //if (dim) fType += TVirtualStreamerInfo::kOffsetL;
01301    fNewType = fType;
01302 }
01303 
01304 //______________________________________________________________________________
01305 void TStreamerObjectPointer::Streamer(TBuffer &R__b)
01306 {
01307    // Stream an object of class TStreamerObjectPointer.
01308 
01309    UInt_t R__s, R__c;
01310    if (R__b.IsReading()) {
01311       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01312       if (R__v > 1) {
01313          R__b.ReadClassBuffer(TStreamerObjectPointer::Class(), this, R__v, R__s, R__c);
01314          return;
01315       }
01316       //====process old versions before automatic schema evolution
01317       TStreamerElement::Streamer(R__b);
01318       R__b.CheckByteCount(R__s, R__c, TStreamerObjectPointer::IsA());
01319    } else {
01320       R__b.WriteClassBuffer(TStreamerObjectPointer::Class(),this);
01321    }
01322 }
01323 
01324 
01325 //______________________________________________________________________________
01326 
01327 //////////////////////////////////////////////////////////////////////////
01328 //                                                                      //
01329 // TStreamerObjectPointerAny implements streaming of pointer to object  //
01330 // not inheriting from TObject.                                         //
01331 //                                                                      //
01332 //////////////////////////////////////////////////////////////////////////
01333 
01334 ClassImp(TStreamerObjectAnyPointer)
01335 
01336 //______________________________________________________________________________
01337 TStreamerObjectAnyPointer::TStreamerObjectAnyPointer()
01338 {
01339    // Default ctor.
01340 
01341 }
01342 
01343 //______________________________________________________________________________
01344 TStreamerObjectAnyPointer::TStreamerObjectAnyPointer(const char *name, const char *title,
01345                                                      Int_t offset, const char *typeName)
01346    : TStreamerElement(name,title,offset,TVirtualStreamerInfo::kAnyP,typeName)
01347 {
01348    // Create a TStreamerObjectAnyPointer object.
01349 
01350    if (strncmp(title,"->",2) == 0) fType = TVirtualStreamerInfo::kAnyp;
01351    fNewType = fType;
01352    Init();
01353 }
01354 
01355 //______________________________________________________________________________
01356 TStreamerObjectAnyPointer::~TStreamerObjectAnyPointer()
01357 {
01358    // TStreamerObjectAnyPointer dtor.
01359 }
01360 
01361 //______________________________________________________________________________
01362 void TStreamerObjectAnyPointer::Init(TObject *)
01363 {
01364    // Setup the element.
01365 
01366    fClassObject = GetClassPointer();
01367    if (fClassObject && fClassObject->InheritsFrom(TObject::Class())) {
01368       fTObjectOffset = fClassObject->GetBaseClassOffset(TObject::Class());
01369    }
01370 }
01371 
01372 //______________________________________________________________________________
01373 const char *TStreamerObjectAnyPointer::GetInclude() const
01374 {
01375    // Return the proper include for this element.
01376 
01377    TClass *cl = GetClassPointer();
01378    if (cl && cl->GetClassInfo()) {
01379       gIncludeName.Form("\"%s\"",cl->GetDeclFileName());
01380    } else {
01381       std::string shortname( TClassEdit::ShortType( GetTypeName(), 1 ) );
01382       gIncludeName.Form("\"%s.h\"",shortname.c_str());
01383    }
01384 
01385    return gIncludeName;
01386 }
01387 
01388 //______________________________________________________________________________
01389 Int_t TStreamerObjectAnyPointer::GetSize() const
01390 {
01391    // Returns size of objectpointer in bytes.
01392 
01393    if (fArrayLength) return fArrayLength*sizeof(void *);
01394    return sizeof(void *);
01395 }
01396 
01397 //______________________________________________________________________________
01398 void TStreamerObjectAnyPointer::SetArrayDim(Int_t dim)
01399 {
01400    // Set number of array dimensions.
01401 
01402    fArrayDim = dim;
01403    //if (dim) fType += TVirtualStreamerInfo::kOffsetL;
01404    fNewType = fType;
01405 }
01406 
01407 //______________________________________________________________________________
01408 void TStreamerObjectAnyPointer::Streamer(TBuffer &R__b)
01409 {
01410    // Stream an object of class TStreamerObjectAnyPointer.
01411 
01412    if (R__b.IsReading()) {
01413       R__b.ReadClassBuffer(TStreamerObjectAnyPointer::Class(), this);
01414    } else {
01415       R__b.WriteClassBuffer(TStreamerObjectAnyPointer::Class(),this);
01416    }
01417 }
01418 
01419 
01420 //______________________________________________________________________________
01421 
01422 //////////////////////////////////////////////////////////////////////////
01423 //                                                                      //
01424 // TSreamerString implements streaming of TString.                      //
01425 //                                                                      //
01426 //////////////////////////////////////////////////////////////////////////
01427 
01428 ClassImp(TStreamerString)
01429 
01430 //______________________________________________________________________________
01431 TStreamerString::TStreamerString()
01432 {
01433    // Default ctor.
01434 
01435 }
01436 
01437 //______________________________________________________________________________
01438 TStreamerString::TStreamerString(const char *name, const char *title, Int_t offset)
01439         : TStreamerElement(name,title,offset,TVirtualStreamerInfo::kTString,"TString")
01440 {
01441    // Create a TStreamerString object.
01442 
01443 }
01444 
01445 //______________________________________________________________________________
01446 TStreamerString::~TStreamerString()
01447 {
01448    // TStreamerString dtor.
01449 }
01450 
01451 //______________________________________________________________________________
01452 const char *TStreamerString::GetInclude() const
01453 {
01454    // Return the proper include for this element.
01455    
01456    gIncludeName.Form("<%s>","TString.h");
01457    return gIncludeName;
01458 }
01459 
01460 //______________________________________________________________________________
01461 Int_t TStreamerString::GetSize() const
01462 {
01463    // Returns size of anyclass in bytes.
01464 
01465    if (fArrayLength) return fArrayLength*sizeof(TString);
01466    return sizeof(TString);
01467 }
01468 
01469 //______________________________________________________________________________
01470 void TStreamerString::Streamer(TBuffer &R__b)
01471 {
01472    // Stream an object of class TStreamerString.
01473 
01474    UInt_t R__s, R__c;
01475    if (R__b.IsReading()) {
01476       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01477       if (R__v > 1) {
01478          R__b.ReadClassBuffer(TStreamerString::Class(), this, R__v, R__s, R__c);
01479          return;
01480       }
01481       //====process old versions before automatic schema evolution
01482       TStreamerElement::Streamer(R__b);
01483       R__b.CheckByteCount(R__s, R__c, TStreamerString::IsA());
01484    } else {
01485       R__b.WriteClassBuffer(TStreamerString::Class(),this);
01486    }
01487 }
01488 
01489 //______________________________________________________________________________
01490 
01491 //////////////////////////////////////////////////////////////////////////
01492 //                                                                      //
01493 // TStreamerSTL implements streamer of STL container.                   //
01494 //                                                                      //
01495 //////////////////////////////////////////////////////////////////////////
01496 
01497 ClassImp(TStreamerSTL)
01498 
01499 //______________________________________________________________________________
01500 TStreamerSTL::TStreamerSTL() : fSTLtype(0),fCtype(0)
01501 {
01502    // Default ctor.
01503 
01504 }
01505 
01506 //______________________________________________________________________________
01507 TStreamerSTL::TStreamerSTL(const char *name, const char *title, Int_t offset,
01508                            const char *typeName, const char *trueType, Bool_t dmPointer)
01509         : TStreamerElement(name,title,offset,kSTL,typeName)
01510 {
01511    // Create a TStreamerSTL object.
01512 
01513    const char *t = trueType;
01514    if (!t || !*t) t = typeName;
01515 
01516    fTypeName = TClassEdit::ShortType(fTypeName,TClassEdit::kDropStlDefault).c_str();
01517 
01518    if (name==typeName /* intentional pointer comparison */
01519        || strcmp(name,typeName)==0) {
01520       // We have a base class.
01521       fName = fTypeName;
01522    }
01523 
01524    Int_t nch = strlen(t);
01525    char *s = new char[nch+1];
01526    strlcpy(s,t,nch+1);
01527    char *sopen  = strchr(s,'<'); 
01528    if (sopen == 0) {
01529       Fatal("TStreamerSTL","For %s, the type name (%s) is not seemingly not a template (template argument not found)", name, s);
01530       return;
01531    }
01532    *sopen  = 0; sopen++;
01533    // We are looking for the first arguments of the STL container, because
01534    // this arguments can be a templates we need to count the < and >
01535    char* current=sopen;
01536    for(int count = 0; *current!='\0'; current++) {
01537       if (*current=='<') count++;
01538       if (*current=='>') {
01539          if (count==0) break;
01540          count--;
01541       }
01542       if (*current==',' && count==0) break;
01543    }
01544    char *sclose = current; *sclose = 0; sclose--;
01545    char *sconst = strstr(sopen,"const ");
01546    char *sbracket = strstr(sopen,"<");
01547    if (sconst && (sbracket==0 || sconst < sbracket)) {
01548       // the string "const" may be part of the classname!
01549       char *pconst = sconst-1;
01550       if (*pconst == ' ' || *pconst == '<' || *pconst == '*' || *pconst == '\0') sopen = sconst + 5;
01551    }
01552    fSTLtype = 0;
01553    fCtype   = 0;
01554    // Any class name that 'contains' the word will be counted
01555    // as a STL container. Is that really what we want.
01556    if      (strstr(s,"vector"))   fSTLtype = kSTLvector;
01557    else if (strstr(s,"list"))     fSTLtype = kSTLlist;
01558    else if (strstr(s,"deque"))    fSTLtype = kSTLdeque;
01559    else if (strstr(s,"multimap")) fSTLtype = kSTLmultimap;
01560    else if (strstr(s,"multiset")) fSTLtype = kSTLmultiset;
01561    else if (strstr(s,"bitset"))   fSTLtype = kSTLbitset;
01562    else if (strstr(s,"map"))      fSTLtype = kSTLmap;
01563    else if (strstr(s,"set"))      fSTLtype = kSTLset;
01564    if (fSTLtype == 0) { delete [] s; return;}
01565    if (dmPointer) fSTLtype += TVirtualStreamerInfo::kOffsetP;
01566 
01567    // find STL contained type
01568    while (*sopen==' ') sopen++;
01569    Bool_t isPointer = kFALSE;
01570    // Find stars outside of any template definitions in the
01571    // first template argument.
01572    char *star = strrchr(sopen,'>');
01573    if (star) star = strchr(star,'*');
01574    else star = strchr(sopen,'*');
01575    if (star) {
01576       isPointer = kTRUE;
01577       *star = 0;
01578       sclose = star - 1;
01579    }
01580    while (*sclose == ' ') {*sclose = 0; sclose--;}
01581 
01582 
01583    TDataType *dt = (TDataType*)gROOT->GetListOfTypes()->FindObject(sopen);
01584    if (fSTLtype == kSTLbitset) {
01585       // Nothing to check
01586    } else if (dt) {
01587       fCtype = dt->GetType();
01588       if (isPointer) fCtype += TVirtualStreamerInfo::kOffsetP;
01589    } else {
01590      // this could also be a nested enums ... which should work ... be let's see.
01591       TClass *cl = TClass::GetClass(sopen);
01592       if (cl) {
01593          if (isPointer) fCtype = TVirtualStreamerInfo::kObjectp;
01594          else           fCtype = TVirtualStreamerInfo::kObject;
01595       } else {
01596          if (gCint->ClassInfo_IsEnum(sopen)) {
01597             if (isPointer) fCtype += TVirtualStreamerInfo::kOffsetP;
01598          } else {
01599             if(strcmp(sopen,"string")) {
01600                // This case can happens when 'this' is a TStreamerElement for
01601                // a STL container containing something for which we do not have
01602                // a TVirtualStreamerInfo (This happens in particular is the collection 
01603                // objects themselves are always empty) and we do not have the
01604                // dictionary/shared library for the container.
01605                if (GetClassPointer() && GetClassPointer()->IsLoaded()) {
01606                   Warning("TStreamerSTL","For %s we could not find any information about the type %s %d %s",fTypeName.Data(),sopen,fSTLtype,s);
01607                }
01608             }
01609          }
01610       }
01611    }
01612    delete [] s;
01613 
01614    if (TStreamerSTL::IsaPointer()) fType = TVirtualStreamerInfo::kSTLp;
01615 }
01616 
01617 //______________________________________________________________________________
01618 TStreamerSTL::~TStreamerSTL()
01619 {
01620    // TStreamerSTL dtor.
01621 }
01622 
01623 //______________________________________________________________________________
01624 Bool_t TStreamerSTL::CannotSplit() const
01625 {
01626    // We can not split STL's which are inside a variable size array.
01627    // At least for now.
01628 
01629    if (IsaPointer()) {
01630       if (GetTitle()[0]=='[') return kTRUE;  // can not split variable size array
01631       return kTRUE;
01632    }
01633 
01634    if (GetArrayDim()>=1 && GetArrayLength()>1) return kTRUE;
01635 
01636    if (TStreamerElement::CannotSplit()) return kTRUE;
01637 
01638    return kFALSE;
01639 }
01640 
01641 //______________________________________________________________________________
01642 Bool_t TStreamerSTL::IsaPointer() const
01643 {
01644    // Return true if the data member is a pointer.
01645 
01646    const char *type_name = GetTypeName();
01647    if ( type_name[strlen(type_name)-1]=='*' ) return kTRUE;
01648    else return kFALSE;
01649 }
01650 
01651 
01652 //______________________________________________________________________________
01653 Bool_t TStreamerSTL::IsBase() const
01654 {
01655    // Return kTRUE if the element represent a base class.
01656 
01657    TString ts(GetName());
01658 
01659    if (strcmp(ts.Data(),GetTypeName())==0) return kTRUE;
01660    if (strcmp(ts.Data(),GetTypeNameBasic())==0) return kTRUE;
01661    return kFALSE;
01662 }
01663 //______________________________________________________________________________
01664 Int_t TStreamerSTL::GetSize() const
01665 {
01666    // Returns size of STL container in bytes.
01667 
01668    // Since the STL collection might or might not be emulated and that the
01669    // sizeof the object depends on this, let's just always retrieve the
01670    // current size!
01671    TClass *cl = GetClassPointer();
01672    UInt_t size = 0;
01673    if (cl==0) {
01674       if (!TestBit(kWarned)) {
01675          Error("GetSize","Could not find the TClass for %s.\n"
01676                "This is likely to have been a typedef, if possible please declare it in CINT to work around the issue\n",fTypeName.Data());
01677          const_cast<TStreamerSTL*>(this)->SetBit(kWarned);
01678       }
01679    } else {
01680       size = cl->Size();
01681    }
01682    
01683    if (fArrayLength) return fArrayLength*size;
01684    return size;
01685 }
01686 
01687 //______________________________________________________________________________
01688 void TStreamerSTL::ls(Option_t *) const
01689 {
01690    // Print the content of the element.
01691 
01692    TString name(kMaxLen);
01693    TString cdim;
01694    name = GetName();
01695    for (Int_t i=0;i<fArrayDim;i++) {
01696       cdim.Form("[%d]",fMaxIndex[i]);
01697       name += cdim;
01698    }
01699    printf("  %-14s %-15s offset=%3d type=%2d %s,stl=%d, ctype=%d, %-20s\n",
01700       GetTypeName(),name.Data(),fOffset,fType,TestBit(kCache)?"(cached)":"",
01701       fSTLtype,fCtype,GetTitle());
01702 }
01703 
01704 //______________________________________________________________________________
01705 const char *TStreamerSTL::GetInclude() const
01706 {
01707    // Return the proper include for this element.
01708 
01709    if      (fSTLtype == kSTLvector)   gIncludeName.Form("<%s>","vector");
01710    else if (fSTLtype == kSTLlist)     gIncludeName.Form("<%s>","list");
01711    else if (fSTLtype == kSTLdeque)    gIncludeName.Form("<%s>","deque");
01712    else if (fSTLtype == kSTLmap)      gIncludeName.Form("<%s>","map");
01713    else if (fSTLtype == kSTLset)      gIncludeName.Form("<%s>","set");
01714    else if (fSTLtype == kSTLmultimap) gIncludeName.Form("<%s>","multimap");
01715    else if (fSTLtype == kSTLmultiset) gIncludeName.Form("<%s>","multiset");
01716    else if (fSTLtype == kSTLbitset)   gIncludeName.Form("<%s>","bitset");
01717    return gIncludeName;
01718 }
01719 
01720 //______________________________________________________________________________
01721 void TStreamerSTL::SetStreamer(TMemberStreamer  *streamer)
01722 {
01723    // Set pointer to Streamer function for this element
01724    // NOTE: we do not take ownership
01725 
01726    fStreamer = streamer;
01727 }
01728 
01729 //______________________________________________________________________________
01730 void TStreamerSTL::Streamer(TBuffer &R__b)
01731 {
01732    // Stream an object of class TStreamerSTL.
01733 
01734    UInt_t R__s, R__c;
01735    if (R__b.IsReading()) {
01736       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01737       if (R__v > 2) {
01738          R__b.ReadClassBuffer(TStreamerSTL::Class(), this, R__v, R__s, R__c);
01739       } else {
01740          //====process old versions before automatic schema evolution
01741          TStreamerElement::Streamer(R__b);
01742          R__b >> fSTLtype;
01743          R__b >> fCtype;
01744          R__b.CheckByteCount(R__s, R__c, TStreamerSTL::IsA());
01745       }
01746       if (IsaPointer()) fType = TVirtualStreamerInfo::kSTLp;
01747       else fType = TVirtualStreamerInfo::kSTL;
01748       if (R__b.GetParent()) { // Avoid resetting during a cloning.
01749          if (fCtype==TVirtualStreamerInfo::kObjectp || fCtype==TVirtualStreamerInfo::kAnyp || fCtype==TVirtualStreamerInfo::kObjectP || fCtype==TVirtualStreamerInfo::kAnyP) {
01750             SetBit(kDoNotDelete); // For backward compatibility
01751          } else if ( fSTLtype == kSTLmap || fSTLtype == kSTLmultimap) {
01752             // Here we would like to set the bit only if one of the element of the pair is a pointer, 
01753             // however we have no easy to determine this short of parsing the class name.
01754             SetBit(kDoNotDelete); // For backward compatibility
01755          }
01756       }
01757       return;
01758    } else {
01759       // To enable forward compatibility we actually save with the old value
01760       Int_t tmp = fType;
01761       fType = TVirtualStreamerInfo::kStreamer;
01762       R__b.WriteClassBuffer(TStreamerSTL::Class(),this);
01763       fType = tmp;
01764    }
01765 }
01766 
01767 //______________________________________________________________________________
01768 
01769 //////////////////////////////////////////////////////////////////////////
01770 //                                                                      //
01771 // TStreamerSTLstring implements streaming std::string.                 //
01772 //                                                                      //
01773 //////////////////////////////////////////////////////////////////////////
01774 
01775 ClassImp(TStreamerSTLstring)
01776 
01777 //______________________________________________________________________________
01778 TStreamerSTLstring::TStreamerSTLstring()
01779 {
01780    // Default ctor.
01781 
01782 }
01783 
01784 //______________________________________________________________________________
01785 TStreamerSTLstring::TStreamerSTLstring(const char *name, const char *title, Int_t offset,
01786                                        const char *typeName, Bool_t dmPointer)
01787         : TStreamerSTL()
01788 {
01789    // Create a TStreamerSTLstring object.
01790 
01791    SetName(name);
01792    SetTitle(title);
01793 
01794    if (dmPointer) {
01795       fType = TVirtualStreamerInfo::kSTLp;
01796    } else {
01797       fType = TVirtualStreamerInfo::kSTL;
01798    }
01799 
01800    fNewType = fType;
01801    fOffset  = offset;
01802    fSTLtype = kSTLstring;
01803    fCtype   = kSTLstring;
01804    fTypeName= typeName;
01805 
01806 }
01807 
01808 //______________________________________________________________________________
01809 TStreamerSTLstring::~TStreamerSTLstring()
01810 {
01811    // TStreamerSTLstring dtor.
01812 }
01813 
01814 //______________________________________________________________________________
01815 const char *TStreamerSTLstring::GetInclude() const
01816 {
01817    // Return the proper include for this element.
01818 
01819    gIncludeName = "<string>";
01820    return gIncludeName;
01821 }
01822 
01823 //______________________________________________________________________________
01824 Int_t TStreamerSTLstring::GetSize() const
01825 {
01826    // Returns size of anyclass in bytes.
01827 
01828    if (fArrayLength) return fArrayLength*sizeof(string);
01829    return sizeof(string);
01830 }
01831 
01832 //______________________________________________________________________________
01833 void TStreamerSTLstring::Streamer(TBuffer &R__b)
01834 {
01835    // Stream an object of class TStreamerSTLstring.
01836 
01837    UInt_t R__s, R__c;
01838    if (R__b.IsReading()) {
01839       Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01840       if (R__v > 1) {
01841          R__b.ReadClassBuffer(TStreamerSTLstring::Class(), this, R__v, R__s, R__c);
01842          return;
01843       }
01844       //====process old versions before automatic schema evolution
01845       TStreamerSTL::Streamer(R__b);
01846       R__b.CheckByteCount(R__s, R__c, TStreamerSTLstring::IsA());
01847    } else {
01848       R__b.WriteClassBuffer(TStreamerSTLstring::Class(),this);
01849    }
01850 }
01851 
01852 //______________________________________________________________________________
01853 
01854 ///////////////////////////////////////////////////////////////////////////////
01855 //                                                                           //
01856 // TStreamerArtificial implements StreamerElement injected by a TSchemaRule. //
01857 //                                                                           //
01858 ///////////////////////////////////////////////////////////////////////////////
01859 
01860 ClassImp(TStreamerSTLstring);
01861 
01862 void TStreamerArtificial::Streamer(TBuffer& /* R__b */)
01863 {
01864    // Avoid streaming the synthetic/artificial streamer elements.
01865 
01866    // Intentionally, nothing to do at all.
01867    return;
01868 }
01869 
01870 ROOT::TSchemaRule::ReadFuncPtr_t     TStreamerArtificial::GetReadFunc()
01871 {
01872    // Return the read function if any.
01873 
01874    return fReadFunc;
01875 }
01876 
01877 ROOT::TSchemaRule::ReadRawFuncPtr_t  TStreamerArtificial::GetReadRawFunc()
01878 {
01879    // Return the raw read function if any.
01880 
01881    return fReadRawFunc;
01882 }

Generated on Tue Jul 5 14:11:55 2011 for ROOT_528-00b_version by  doxygen 1.5.1