TObject.cxx

Go to the documentation of this file.
00001 // @(#)root/base:$Id: TObject.cxx 36061 2010-10-04 16:05:51Z pcanal $
00002 // Author: Rene Brun   26/12/94
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 // TObject                                                              //
00015 //                                                                      //
00016 // Mother of all ROOT objects.                                          //
00017 //                                                                      //
00018 // The TObject class provides default behaviour and protocol for all    //
00019 // objects in the ROOT system. It provides protocol for object I/O,     //
00020 // error handling, sorting, inspection, printing, drawing, etc.         //
00021 // Every object which inherits from TObject can be stored in the        //
00022 // ROOT collection classes.                                             //
00023 // TObject's bits can be used as flags, bits 0 - 13 and 24-31 are       //
00024 // reserved as  global bits while bits 14 - 23 can be used in different //
00025 // class hierarchies (watch out for overlaps).                          //
00026 //                                                                      //
00027 //////////////////////////////////////////////////////////////////////////
00028 
00029 #include <string.h>
00030 #if !defined(WIN32) && !defined(__MWERKS__) && !defined(R__SOLARIS)
00031 #include <strings.h>
00032 #endif
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 
00036 #include "Varargs.h"
00037 #include "Riostream.h"
00038 #include "TObject.h"
00039 #include "TClass.h"
00040 #include "TGuiFactory.h"
00041 #include "TMethod.h"
00042 #include "TROOT.h"
00043 #include "TError.h"
00044 #include "TObjectTable.h"
00045 #include "TVirtualPad.h"
00046 #include "TInterpreter.h"
00047 #include "TMemberInspector.h"
00048 #include "TObjString.h"
00049 #include "TRefTable.h"
00050 #include "TProcessID.h"
00051 
00052 class TDumpMembers : public TMemberInspector {
00053    // Implemented in TClass.cxx
00054 public:
00055    TDumpMembers() { }
00056    void Inspect(TClass *cl, const char *parent, const char *name, const void *addr);
00057 };
00058 
00059 Long_t TObject::fgDtorOnly = 0;
00060 Bool_t TObject::fgObjectStat = kTRUE;
00061 
00062 ClassImp(TObject)
00063 
00064 //______________________________________________________________________________
00065 TObject::TObject() : fUniqueID(0), fBits(kNotDeleted)
00066 {
00067    // TObject constructor. It sets the two data words of TObject to their
00068    // initial values. The unique ID is set to 0 and the status word is
00069    // set depending if the object is created on the stack or allocated
00070    // on the heap. Depending on the ROOT environment variable "Root.MemStat"
00071    // (see TEnv) the object is added to the global TObjectTable for
00072    // bookkeeping.
00073 
00074    if (TStorage::IsOnHeap(this))
00075       fBits |= kIsOnHeap;
00076 
00077    if (fgObjectStat) TObjectTable::AddObj(this);
00078 }
00079 
00080 //______________________________________________________________________________
00081 TObject::TObject(const TObject &obj)
00082 {
00083    // TObject copy ctor.
00084 
00085    fUniqueID = obj.fUniqueID;  // when really unique don't copy
00086    fBits     = obj.fBits;
00087 
00088    if (TStorage::IsOnHeap(this))
00089       fBits |= kIsOnHeap;
00090    else
00091       fBits &= ~kIsOnHeap;
00092 
00093    fBits &= ~kIsReferenced;
00094    fBits &= ~kCanDelete;
00095 
00096    if (fgObjectStat) TObjectTable::AddObj(this);
00097 }
00098 
00099 //______________________________________________________________________________
00100 TObject& TObject::operator=(const TObject &rhs)
00101 {
00102    // TObject assignment operator.
00103 
00104    if (this != &rhs) {
00105       fUniqueID = rhs.fUniqueID;  // when really unique don't copy
00106       if (IsOnHeap()) {           // test uses fBits so don't move next line
00107          fBits  = rhs.fBits;
00108          fBits |= kIsOnHeap;
00109       } else {
00110          fBits  = rhs.fBits;
00111          fBits &= ~kIsOnHeap;
00112       }
00113       fBits &= ~kIsReferenced;
00114       fBits &= ~kCanDelete;
00115    }
00116    return *this;
00117 }
00118 
00119 //______________________________________________________________________________
00120 void TObject::Copy(TObject &obj) const
00121 {
00122    // Copy this to obj.
00123 
00124    obj.fUniqueID = fUniqueID;   // when really unique don't copy
00125    if (obj.IsOnHeap()) {        // test uses fBits so don't move next line
00126       obj.fBits  = fBits;
00127       obj.fBits |= kIsOnHeap;
00128    } else {
00129       obj.fBits  = fBits;
00130       obj.fBits &= ~kIsOnHeap;
00131    }
00132    obj.fBits &= ~kIsReferenced;
00133    obj.fBits &= ~kCanDelete;
00134 }
00135 
00136 //______________________________________________________________________________
00137 TObject::~TObject()
00138 {
00139    // TObject destructor. Removes object from all canvases and object browsers
00140    // if observer bit is on and remove from the global object table.
00141 
00142    // if (!TestBit(kNotDeleted))
00143    //    Fatal("~TObject", "object deleted twice");
00144 
00145    if (gROOT) {
00146       if (gROOT->MustClean()) {
00147          if (gROOT == this) return;
00148          if (TestBit(kMustCleanup)) {
00149             gROOT->GetListOfCleanups()->RecursiveRemove(this);
00150          }
00151       }
00152    }
00153 
00154    fBits &= ~kNotDeleted;
00155 
00156    if (fgObjectStat && gObjectTable) gObjectTable->Remove(this);
00157 }
00158 
00159 //______________________________________________________________________________
00160 void TObject::AppendPad(Option_t *option)
00161 {
00162    // Append graphics object to current pad. In case no current pad is set
00163    // yet, create a default canvas with the name "c1".
00164 
00165    if (!gPad) {
00166       gROOT->MakeDefCanvas();
00167    }
00168    if (!gPad->IsEditable()) return;
00169    SetBit(kMustCleanup);
00170    gPad->GetListOfPrimitives()->Add(this,option);
00171    gPad->Modified(kTRUE);
00172 }
00173 
00174 //______________________________________________________________________________
00175 void TObject::Browse(TBrowser *b)
00176 {
00177    // Browse object. May be overridden for another default action
00178 
00179    //Inspect();
00180    TClass::AutoBrowse(this,b);
00181 }
00182 
00183 //______________________________________________________________________________
00184 const char *TObject::ClassName() const
00185 {
00186    // Returns name of class to which the object belongs.
00187 
00188    return IsA()->GetName();
00189 }
00190 
00191 //______________________________________________________________________________
00192 TObject *TObject::Clone(const char *) const
00193 {
00194    // Make a clone of an object using the Streamer facility.
00195    // If the object derives from TNamed, this function is called
00196    // by TNamed::Clone. TNamed::Clone uses the optional argument to set
00197    // a new name to the newly created object.
00198    //
00199    // If the object class has a DirectoryAutoAdd function, it will be
00200    // called at the end of the function with the parameter gDirectory.
00201    // This usually means that the object will be appended to the current
00202    // ROOT directory.
00203 
00204    if (gDirectory) return gDirectory->CloneObject(this);
00205    else            return 0;
00206 }
00207 
00208 //______________________________________________________________________________
00209 Int_t TObject::Compare(const TObject *) const
00210 {
00211    // Compare abstract method. Must be overridden if a class wants to be able
00212    // to compare itself with other objects. Must return -1 if this is smaller
00213    // than obj, 0 if objects are equal and 1 if this is larger than obj.
00214 
00215    AbstractMethod("Compare");
00216    return 0;
00217 }
00218 
00219 //______________________________________________________________________________
00220 void TObject::Delete(Option_t *)
00221 {
00222    // Delete this object. Typically called as a command via the interpreter.
00223    // Normally use "delete" operator when object has been allocated on the heap.
00224 
00225    if (IsOnHeap()) {
00226       // Delete object from CINT symbol table so it can not be used anymore.
00227       // CINT object are always on the heap.
00228       gInterpreter->DeleteGlobal(this);
00229 
00230       delete this;
00231    }
00232 }
00233 
00234 
00235 //______________________________________________________________________________
00236 Int_t TObject::DistancetoPrimitive(Int_t, Int_t)
00237 {
00238    // Computes distance from point (px,py) to the object.
00239    // This member function must be implemented for each graphics primitive.
00240    // This default function returns a big number (999999).
00241 
00242    // AbstractMethod("DistancetoPrimitive");
00243    return 999999;
00244 }
00245 
00246 //______________________________________________________________________________
00247 void TObject::Draw(Option_t *option)
00248 {
00249    // Default Draw method for all objects
00250 
00251    AppendPad(option);
00252 }
00253 
00254 //______________________________________________________________________________
00255 void TObject::DrawClass() const
00256 {
00257    // Draw class inheritance tree of the class to which this object belongs.
00258    // If a class B inherits from a class A, description of B is drawn
00259    // on the right side of description of A.
00260    // Member functions overridden by B are shown in class A with a blue line
00261    // crossing-out the corresponding member function.
00262    // The following picture is the class inheritance tree of class TPaveLabel:
00263    //Begin_Html
00264    /*
00265    <img src="gif/drawclass.gif">
00266    */
00267    //End_Html
00268 
00269    IsA()->Draw();
00270 }
00271 
00272 //______________________________________________________________________________
00273 TObject *TObject::DrawClone(Option_t *option) const
00274 {
00275    // Draw a clone of this object in the current pad
00276 
00277    TVirtualPad *pad    = gROOT->GetSelectedPad();
00278    TVirtualPad *padsav = gPad;
00279    if (pad) pad->cd();
00280 
00281    TObject *newobj = Clone();
00282    if (!newobj) return 0;
00283    if (pad) {
00284       if (strlen(option)) pad->GetListOfPrimitives()->Add(newobj,option);
00285       else                pad->GetListOfPrimitives()->Add(newobj,GetDrawOption());
00286       pad->Modified(kTRUE);
00287       pad->Update();
00288       if (padsav) padsav->cd();
00289       return newobj;
00290    }
00291    if (strlen(option))  newobj->Draw(option);
00292    else                 newobj->Draw(GetDrawOption());
00293    if (padsav) padsav->cd();
00294 
00295    return newobj;
00296 }
00297 
00298 //______________________________________________________________________________
00299 void TObject::Dump() const
00300 {
00301    // Dump contents of object on stdout.
00302    // Using the information in the object dictionary (class TClass)
00303    // each data member is interpreted.
00304    // If a data member is a pointer, the pointer value is printed
00305    //
00306    // The following output is the Dump of a TArrow object:
00307    //   fAngle                   0           Arrow opening angle (degrees)
00308    //   fArrowSize               0.2         Arrow Size
00309    //   fOption.*fData
00310    //   fX1                      0.1         X of 1st point
00311    //   fY1                      0.15        Y of 1st point
00312    //   fX2                      0.67        X of 2nd point
00313    //   fY2                      0.83        Y of 2nd point
00314    //   fUniqueID                0           object unique identifier
00315    //   fBits                    50331648    bit field status word
00316    //   fLineColor               1           line color
00317    //   fLineStyle               1           line style
00318    //   fLineWidth               1           line width
00319    //   fFillColor               19          fill area color
00320    //   fFillStyle               1001        fill area style
00321 
00322    if (sizeof(this) == 4)
00323       Printf("==> Dumping object at: 0x%08lx, name=%s, class=%s\n",(Long_t)this,GetName(),ClassName());
00324    else
00325       Printf("==> Dumping object at: 0x%016lx, name=%s, class=%s\n",(Long_t)this,GetName(),ClassName());
00326 
00327    TDumpMembers dm;
00328    ((TObject*)this)->ShowMembers(dm);
00329 }
00330 
00331 //______________________________________________________________________________
00332 void TObject::Execute(const char *method, const char *params, Int_t *error)
00333 {
00334    // Execute method on this object with the given parameter string, e.g.
00335    // "3.14,1,\"text\"".
00336 
00337    if (!IsA()) return;
00338 
00339    Bool_t must_cleanup = TestBit(kMustCleanup);
00340 
00341    gInterpreter->Execute(this, IsA(), method, params, error);
00342 
00343    if (gPad && must_cleanup) gPad->Modified();
00344 }
00345 
00346 //______________________________________________________________________________
00347 void TObject::Execute(TMethod *method, TObjArray *params, Int_t *error)
00348 {
00349    // Execute method on this object with parameters stored in the TObjArray.
00350    // The TObjArray should contain an argv vector like:
00351    //
00352    //  argv[0] ... argv[n] = the list of TObjString parameters
00353 
00354    if (!IsA()) return;
00355 
00356    Bool_t must_cleanup = TestBit(kMustCleanup);
00357 
00358    gInterpreter->Execute(this, IsA(), method, params, error);
00359 
00360    if (gPad && must_cleanup) gPad->Modified();
00361 }
00362 
00363 
00364 //______________________________________________________________________________
00365 void TObject::ExecuteEvent(Int_t, Int_t, Int_t)
00366 {
00367    // Execute action corresponding to an event at (px,py). This method
00368    // must be overridden if an object can react to graphics events.
00369 
00370    // AbstractMethod("ExecuteEvent");
00371 }
00372 
00373 //______________________________________________________________________________
00374 TObject *TObject::FindObject(const char *) const
00375 {
00376    // Must be redefined in derived classes.
00377    // This function is typycally used with TCollections, but can also be used
00378    // to find an object by name inside this object.
00379 
00380    return 0;
00381 }
00382 
00383 //______________________________________________________________________________
00384 TObject *TObject::FindObject(const TObject *) const
00385 {
00386    // Must be redefined in derived classes.
00387    // This function is typycally used with TCollections, but can also be used
00388    // to find an object inside this object.
00389 
00390    return 0;
00391 }
00392 
00393 //______________________________________________________________________________
00394 Option_t *TObject::GetDrawOption() const
00395 {
00396    // Get option used by the graphics system to draw this object.
00397    // Note that before calling object.GetDrawOption(), you must
00398    // have called object.Draw(..) before in the current pad.
00399 
00400    if (!gPad) return "";
00401 
00402    TListIter next(gPad->GetListOfPrimitives());
00403    TObject *obj;
00404    while ((obj = next())) {
00405       if (obj == this) return next.GetOption();
00406    }
00407    return "";
00408 }
00409 
00410 //______________________________________________________________________________
00411 const char *TObject::GetName() const
00412 {
00413    // Returns name of object. This default method returns the class name.
00414    // Classes that give objects a name should override this method.
00415 
00416    return IsA()->GetName();
00417 }
00418 
00419 //______________________________________________________________________________
00420 const char *TObject::GetIconName() const
00421 {
00422    // Returns mime type name of object. Used by the TBrowser (via TGMimeTypes
00423    // class). Override for class of which you would like to have different
00424    // icons for objects of the same class.
00425 
00426    return 0;
00427 }
00428 
00429 //______________________________________________________________________________
00430 UInt_t TObject::GetUniqueID() const
00431 {
00432    // Return the unique object id.
00433 
00434    return fUniqueID;
00435 }
00436 
00437 //______________________________________________________________________________
00438 char *TObject::GetObjectInfo(Int_t px, Int_t py) const
00439 {
00440    // Returns string containing info about the object at position (px,py).
00441    // This method is typically overridden by classes of which the objects
00442    // can report peculiarities for different positions.
00443    // Returned string will be re-used (lock in MT environment).
00444 
00445    if (!gPad) return (char*)"";
00446    static char info[64];
00447    Float_t x = gPad->AbsPixeltoX(px);
00448    Float_t y = gPad->AbsPixeltoY(py);
00449    snprintf(info,64,"x=%g, y=%g",gPad->PadtoX(x),gPad->PadtoY(y));
00450    return info;
00451 }
00452 
00453 //______________________________________________________________________________
00454 const char *TObject::GetTitle() const
00455 {
00456    // Returns title of object. This default method returns the class title
00457    // (i.e. description). Classes that give objects a title should override
00458    // this method.
00459 
00460    return IsA()->GetTitle();
00461 }
00462 
00463 
00464 //______________________________________________________________________________
00465 Bool_t TObject::HandleTimer(TTimer *)
00466 {
00467    // Execute action in response of a timer timing out. This method
00468    // must be overridden if an object has to react to timers.
00469 
00470    return kFALSE;
00471 }
00472 
00473 //______________________________________________________________________________
00474 ULong_t TObject::Hash() const
00475 {
00476    // Return hash value for this object.
00477 
00478    //return (ULong_t) this >> 2;
00479    const void *ptr = this;
00480    return TString::Hash(&ptr, sizeof(void*));
00481 }
00482 
00483 //______________________________________________________________________________
00484 Bool_t TObject::InheritsFrom(const char *classname) const
00485 {
00486    // Returns kTRUE if object inherits from class "classname".
00487 
00488    return IsA()->InheritsFrom(classname);
00489 }
00490 
00491 //______________________________________________________________________________
00492 Bool_t TObject::InheritsFrom(const TClass *cl) const
00493 {
00494    // Returns kTRUE if object inherits from TClass cl.
00495 
00496    return IsA()->InheritsFrom(cl);
00497 }
00498 
00499 //______________________________________________________________________________
00500 void TObject::Inspect() const
00501 {
00502    // Dump contents of this object in a graphics canvas.
00503    // Same action as Dump but in a graphical form.
00504    // In addition pointers to other objects can be followed.
00505    //
00506    // The following picture is the Inspect of a histogram object:
00507    //Begin_Html
00508    /*
00509    <img src="gif/hpxinspect.gif">
00510    */
00511    //End_Html
00512 
00513    gGuiFactory->CreateInspectorImp(this, 400, 200);
00514 }
00515 
00516 //______________________________________________________________________________
00517 Bool_t TObject::IsFolder() const
00518 {
00519    // Returns kTRUE in case object contains browsable objects (like containers
00520    // or lists of other objects).
00521 
00522    return kFALSE;
00523 }
00524 
00525 //______________________________________________________________________________
00526 Bool_t TObject::IsEqual(const TObject *obj) const
00527 {
00528    // Default equal comparison (objects are equal if they have the same
00529    // address in memory). More complicated classes might want to override
00530    // this function.
00531 
00532    return obj == this;
00533 }
00534 
00535 //______________________________________________________________________________
00536 void TObject::ls(Option_t *) const
00537 {
00538    // The ls function lists the contents of a class on stdout. Ls output
00539    // is typically much less verbose then Dump().
00540 
00541    TROOT::IndentLevel();
00542    cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << " : "
00543         << Int_t(TestBit(kCanDelete))  <<" at: "<<this<< endl;
00544 }
00545 
00546 //______________________________________________________________________________
00547 Bool_t TObject::Notify()
00548 {
00549    // This method must be overridden to handle object notifcation.
00550 
00551    return kFALSE;
00552 }
00553 
00554 //______________________________________________________________________________
00555 void TObject::Paint(Option_t *)
00556 {
00557    // This method must be overridden if a class wants to paint itself.
00558    // The difference between Paint() and Draw() is that when a object
00559    // draws itself it is added to the display list of the pad in
00560    // which it is drawn (and automatically redrawn whenever the pad is
00561    // redrawn). While paint just draws the object without adding it to
00562    // the pad display list.
00563 
00564    // AbstractMethod("Paint");
00565 }
00566 
00567 //______________________________________________________________________________
00568 void TObject::Pop()
00569 {
00570    // Pop on object drawn in a pad to the top of the display list. I.e. it
00571    // will be drawn last and on top of all other primitives.
00572 
00573    if (!gPad) return;
00574 
00575    if (this == gPad->GetListOfPrimitives()->Last()) return;
00576 
00577    TListIter next(gPad->GetListOfPrimitives());
00578    TObject *obj;
00579    while ((obj = next()))
00580       if (obj == this) {
00581          char *opt = StrDup(next.GetOption());
00582          gPad->GetListOfPrimitives()->Remove((TObject*)this);
00583          gPad->GetListOfPrimitives()->AddLast(this, opt);
00584          gPad->Modified();
00585          delete [] opt;
00586          return;
00587       }
00588 }
00589 
00590 //______________________________________________________________________________
00591 void TObject::Print(Option_t *) const
00592 {
00593    // This method must be overridden when a class wants to print itself.
00594 
00595    cout <<"OBJ: " << IsA()->GetName() << "\t" << GetName() << "\t" << GetTitle() << endl;
00596 }
00597 
00598 //______________________________________________________________________________
00599 Int_t TObject::Read(const char *name)
00600 {
00601    // Read contents of object with specified name from the current directory.
00602    // First the key with the given name is searched in the current directory,
00603    // next the key buffer is deserialized into the object.
00604    // The object must have been created before via the default constructor.
00605    // See TObject::Write().
00606 
00607    if (gDirectory) return gDirectory->ReadTObject(this,name);
00608    else            return 0;
00609 }
00610 
00611 //______________________________________________________________________________
00612 void TObject::RecursiveRemove(TObject *)
00613 {
00614    // Recursively remove this object from a list. Typically implemented
00615    // by classes that can contain mulitple references to a same object.
00616 
00617 }
00618 
00619 
00620 //______________________________________________________________________________
00621 void TObject::SaveAs(const char *filename, Option_t *option) const
00622 {
00623    // Save this object in the file specified by filename.
00624    // if (filename contains ".root" the object is saved in filename (root binary file)
00625    // if (filename contains ".xml"  the object is saved in filename (xml ascii file)
00626    //  otherwise the object is written to filename as a CINT/C++ script.
00627    //  The C++ code to rebuild this object is generated via SavePrimitive().
00628    //  The option parameter is passed to SavePrimitive. By default it is
00629    //  en empty string. It can be used to specify the Draw option
00630    //  in the code generated by SavePrimitive.
00631    // The function is available via the object context menu.
00632 
00633    //==============Save object as a root file===============================
00634    if (filename && strstr(filename,".root")) {
00635       if (gDirectory) gDirectory->SaveObjectAs(this,filename,"");
00636       return;
00637    }
00638 
00639    //==============Save object as a XML file================================
00640    if (filename && strstr(filename,".xml")) {
00641       if (gDirectory) gDirectory->SaveObjectAs(this,filename,"");
00642       return;
00643    }
00644 
00645    //==============Save as a C++ CINT file================================
00646    char *fname = 0;
00647    if (filename && strlen(filename) > 0) {
00648       fname = (char*)filename;
00649    } else {
00650       fname = Form("%s.C", GetName());
00651    }
00652    ofstream out;
00653    out.open(fname, ios::out);
00654    if (!out.good ()) {
00655       Error("SaveAs", "cannot open file: %s", fname);
00656       return;
00657    }
00658    out <<"{"<<endl;
00659    out <<"//========= Macro generated from object: "<<GetName()<<"/"<<GetTitle()<<endl;
00660    out <<"//========= by ROOT version"<<gROOT->GetVersion()<<endl;
00661    ((TObject*)this)->SavePrimitive(out,option);
00662    out <<"}"<<endl;
00663    out.close();
00664    Info("SaveAs", "C++ Macro file: %s has been generated", fname);
00665 }
00666 
00667 //______________________________________________________________________________
00668 void TObject::SavePrimitive(ostream &out, Option_t * /*= ""*/)
00669 {
00670    // Save a primitive as a C++ statement(s) on output stream "out".
00671 
00672    out << "//Primitive: " << GetName() << "/" << GetTitle()
00673        <<". You must implement " << ClassName() << "::SavePrimitive" << endl;
00674 }
00675 
00676 //______________________________________________________________________________
00677 void TObject::SetDrawOption(Option_t *option)
00678 {
00679    // Set drawing option for object. This option only affects
00680    // the drawing style and is stored in the option field of the
00681    // TObjOptLink supporting a TPad's primitive list (TList).
00682    // Note that it does not make sense to call object.SetDrawOption(option)
00683    // before having called object.Draw().
00684 
00685    if (!gPad || !option) return;
00686 
00687    TListIter next(gPad->GetListOfPrimitives());
00688    delete gPad->FindObject("Tframe");
00689    TObject *obj;
00690    while ((obj = next()))
00691       if (obj == this) {
00692          next.SetOption(option);
00693          return;
00694       }
00695 }
00696 
00697 //______________________________________________________________________________
00698 void TObject::SetBit(UInt_t f, Bool_t set)
00699 {
00700    // Set or unset the user status bits as specified in f.
00701 
00702    if (set)
00703       SetBit(f);
00704    else
00705       ResetBit(f);
00706 }
00707 
00708 //______________________________________________________________________________
00709 void TObject::SetUniqueID(UInt_t uid)
00710 {
00711    // Set the unique object id.
00712 
00713    fUniqueID = uid;
00714 }
00715 
00716 //______________________________________________________________________________
00717 void TObject::UseCurrentStyle()
00718 {
00719    // Set current style settings in this object
00720    // This function is called when either TCanvas::UseCurrentStyle
00721    // or TROOT::ForceStyle have been invoked.
00722 }
00723 
00724 //______________________________________________________________________________
00725 Int_t TObject::Write(const char *name, Int_t option, Int_t bufsize) const
00726 {
00727    // Write this object to the current directory.
00728    // The data structure corresponding to this object is serialized.
00729    // The corresponding buffer is written to the current directory
00730    // with an associated key with name "name".
00731    //
00732    // Writing an object to a file involves the following steps:
00733    //
00734    //  -Creation of a support TKey object in the current directory.
00735    //   The TKey object creates a TBuffer object.
00736    //
00737    //  -The TBuffer object is filled via the class::Streamer function.
00738    //
00739    //  -If the file is compressed (default) a second buffer is created to
00740    //   hold the compressed buffer.
00741    //
00742    //  -Reservation of the corresponding space in the file by looking
00743    //   in the TFree list of free blocks of the file.
00744    //
00745    //  -The buffer is written to the file.
00746    //
00747    //  Bufsize can be given to force a given buffer size to write this object.
00748    //  By default, the buffersize will be taken from the average buffer size
00749    //  of all objects written to the current file so far.
00750    //
00751    //  If a name is specified, it will be the name of the key.
00752    //  If name is not given, the name of the key will be the name as returned
00753    //  by GetName().
00754    //
00755    //  The option can be a combination of:
00756    //    kSingleKey, kOverwrite or kWriteDelete
00757    //  Using the kOverwrite option a previous key with the same name is
00758    //  overwritten. The previous key is deleted before writing the new object.
00759    //  Using the kWriteDelete option a previous key with the same name is
00760    //  deleted only after the new object has been written. This option
00761    //  is safer than kOverwrite but it is slower.
00762    //  The kSingleKey option is only used by TCollection::Write() to write
00763    //  a container with a single key instead of each object in the container
00764    //  with its own key.
00765    //
00766    //  An object is read from the file into memory via TKey::Read() or
00767    //  via TObject::Read().
00768    //
00769    //  The function returns the total number of bytes written to the file.
00770    //  It returns 0 if the object cannot be written.
00771 
00772    TString opt = "";
00773    if (option & kSingleKey)   opt += "SingleKey";
00774    if (option & kOverwrite)   opt += "OverWrite";
00775    if (option & kWriteDelete) opt += "WriteDelete";
00776 
00777    if (gDirectory) return gDirectory->WriteTObject(this,name,opt.Data(),bufsize);
00778    else {
00779       const char *objname = "no name specified";
00780       if (name) objname = name;
00781       else objname = GetName();
00782       Error("Write","The current directory (gDirectory) is null. The object (%s) has not been written.",objname);
00783       return 0;
00784    }
00785 }
00786 
00787 //______________________________________________________________________________
00788 Int_t TObject::Write(const char *name, Int_t option, Int_t bufsize)
00789 {
00790    // Write this object to the current directory. For more see the
00791    // const version of this method.
00792 
00793    return ((const TObject*)this)->Write(name, option, bufsize);
00794 }
00795 
00796 //______________________________________________________________________________
00797 void TObject::Streamer(TBuffer &R__b)
00798 {
00799    // Stream an object of class TObject.
00800 
00801    if (IsA()->CanIgnoreTObjectStreamer()) return;
00802    UShort_t pidf;
00803    if (R__b.IsReading()) {
00804       R__b.SkipVersion(); // Version_t R__v = R__b.ReadVersion(); if (R__v) { }
00805       R__b >> fUniqueID;
00806       R__b >> fBits;
00807       fBits |= kIsOnHeap;  // by definition de-serialized object is on heap
00808       if (TestBit(kIsReferenced)) {
00809          //if the object is referenced, we must read its old address
00810          //and store it in the ProcessID map in gROOT
00811          R__b >> pidf;
00812          pidf += R__b.GetPidOffset();
00813          TProcessID *pid = R__b.ReadProcessID(pidf);
00814          if (pid) {
00815             UInt_t gpid = pid->GetUniqueID();
00816             if (gpid>=0xff) {
00817                fUniqueID = fUniqueID | 0xff000000;
00818             } else {
00819                fUniqueID = ( fUniqueID & 0xffffff) + (gpid<<24);
00820             }
00821             pid->PutObjectWithID(this);
00822          }
00823       }
00824    } else {
00825       R__b.WriteVersion(TObject::IsA());
00826       if (!TestBit(kIsReferenced)) {
00827          R__b << fUniqueID;
00828          R__b << fBits;
00829       } else {
00830          //if the object is referenced, we must save its address/file_pid
00831          UInt_t uid = fUniqueID & 0xffffff;
00832          R__b << uid;
00833          R__b << fBits;
00834          TProcessID *pid = TProcessID::GetProcessWithUID(fUniqueID,this);
00835          //add uid to the TRefTable if there is one
00836          TRefTable *table = TRefTable::GetRefTable();
00837          if(table) table->Add(uid, pid);
00838          pidf = R__b.WriteProcessID(pid);
00839          R__b << pidf;
00840       }
00841    }
00842 }
00843 
00844 //______________________________________________________________________________
00845 
00846 //---- error handling ----------------------------------------------------------
00847 
00848 //______________________________________________________________________________
00849 void TObject::DoError(int level, const char *location, const char *fmt, va_list va) const
00850 {
00851    // Interface to ErrorHandler (protected).
00852 
00853    const char *classname = "UnknownClass";
00854    if (TROOT::Initialized())
00855       classname = ClassName();
00856 
00857    ::ErrorHandler(level, Form("%s::%s", classname, location), fmt, va);
00858 }
00859 
00860 //______________________________________________________________________________
00861 void TObject::Info(const char *location, const char *va_(fmt), ...) const
00862 {
00863    // Issue info message. Use "location" to specify the method where the
00864    // warning occured. Accepts standard printf formatting arguments.
00865 
00866    va_list ap;
00867    va_start(ap, va_(fmt));
00868    DoError(kInfo, location, va_(fmt), ap);
00869    va_end(ap);
00870 }
00871 
00872 //______________________________________________________________________________
00873 void TObject::Warning(const char *location, const char *va_(fmt), ...) const
00874 {
00875    // Issue warning message. Use "location" to specify the method where the
00876    // warning occured. Accepts standard printf formatting arguments.
00877 
00878    va_list ap;
00879    va_start(ap, va_(fmt));
00880    DoError(kWarning, location, va_(fmt), ap);
00881    va_end(ap);
00882    if (TROOT::Initialized())
00883       gROOT->Message(1001, this);
00884 }
00885 
00886 //______________________________________________________________________________
00887 void TObject::Error(const char *location, const char *va_(fmt), ...) const
00888 {
00889    // Issue error message. Use "location" to specify the method where the
00890    // error occured. Accepts standard printf formatting arguments.
00891 
00892    va_list ap;
00893    va_start(ap, va_(fmt));
00894    DoError(kError, location, va_(fmt), ap);
00895    va_end(ap);
00896    if (TROOT::Initialized())
00897       gROOT->Message(1002, this);
00898 }
00899 
00900 //______________________________________________________________________________
00901 void TObject::SysError(const char *location, const char *va_(fmt), ...) const
00902 {
00903    // Issue system error message. Use "location" to specify the method where
00904    // the system error occured. Accepts standard printf formatting arguments.
00905 
00906    va_list ap;
00907    va_start(ap, va_(fmt));
00908    DoError(kSysError, location, va_(fmt), ap);
00909    va_end(ap);
00910    if (TROOT::Initialized())
00911       gROOT->Message(1003, this);
00912 }
00913 
00914 //______________________________________________________________________________
00915 void TObject::Fatal(const char *location, const char *va_(fmt), ...) const
00916 {
00917    // Issue fatal error message. Use "location" to specify the method where the
00918    // fatal error occured. Accepts standard printf formatting arguments.
00919 
00920    va_list ap;
00921    va_start(ap, va_(fmt));
00922    DoError(kFatal, location, va_(fmt), ap);
00923    va_end(ap);
00924    if (TROOT::Initialized())
00925       gROOT->Message(1004, this);
00926 }
00927 
00928 //______________________________________________________________________________
00929 void TObject::AbstractMethod(const char *method) const
00930 {
00931    // Use this method to implement an "abstract" method that you don't
00932    // want to leave purely abstract.
00933 
00934    Warning(method, "this method must be overridden!");
00935 }
00936 
00937 //______________________________________________________________________________
00938 void TObject::MayNotUse(const char *method) const
00939 {
00940    // Use this method to signal that a method (defined in a base class)
00941    // may not be called in a derived class (in principle against good
00942    // design since a child class should not provide less functionality
00943    // than its parent, however, sometimes it is necessary).
00944 
00945    Warning(method, "may not use this method");
00946 }
00947 
00948 
00949 //----------------- Static data members access ---------------------------------
00950 
00951 //______________________________________________________________________________
00952 Bool_t TObject::GetObjectStat()
00953 {
00954    // Get status of object stat flag.
00955 
00956    return fgObjectStat;
00957 }
00958 //______________________________________________________________________________
00959 void TObject::SetObjectStat(Bool_t stat)
00960 {
00961    // Turn on/off tracking of objects in the TObjectTable.
00962 
00963    fgObjectStat = stat;
00964 }
00965 
00966 //______________________________________________________________________________
00967 Long_t TObject::GetDtorOnly()
00968 {
00969    //return destructor only flag
00970    return fgDtorOnly;
00971 }
00972 
00973 //______________________________________________________________________________
00974 void TObject::SetDtorOnly(void *obj)
00975 {
00976    //set destructor only flag
00977    fgDtorOnly = (Long_t) obj;
00978 }
00979 
00980 //______________________________________________________________________________
00981 void TObject::operator delete(void *ptr)
00982 {
00983    //operator delete
00984    if ((Long_t) ptr != fgDtorOnly)
00985       TStorage::ObjectDealloc(ptr);
00986    else
00987       fgDtorOnly = 0;
00988 }
00989 
00990 //______________________________________________________________________________
00991 void TObject::operator delete[](void *ptr)
00992 {
00993    //operator delete []
00994    if ((Long_t) ptr != fgDtorOnly)
00995       TStorage::ObjectDealloc(ptr);
00996    else
00997       fgDtorOnly = 0;
00998 }
00999 
01000 #ifdef R__PLACEMENTDELETE
01001 //______________________________________________________________________________
01002 void TObject::operator delete(void *ptr, void *vp)
01003 {
01004    // Only called by placement new when throwing an exception.
01005 
01006    TStorage::ObjectDealloc(ptr, vp);
01007 }
01008 
01009 //______________________________________________________________________________
01010 void TObject::operator delete[](void *ptr, void *vp)
01011 {
01012    // Only called by placement new[] when throwing an exception.
01013 
01014    TStorage::ObjectDealloc(ptr, vp);
01015 }
01016 #endif

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