TDataSet.cxx

Go to the documentation of this file.
00001 // @(#)root/table:$Id: TDataSet.cxx 34263 2010-07-01 07:08:27Z brun $
00002 // Author: Valery Fine(fine@mail.cern.ch)   03/07/98
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 #include "Riostream.h"
00013 #include "TSystem.h"
00014 #include "TDataSetIter.h"
00015 #include "TDataSet.h"
00016 
00017 #include "TROOT.h"
00018 #include "TBrowser.h"
00019 
00020 #include "TSystem.h"
00021 #include <assert.h>
00022 
00023 //////////////////////////////////////////////////////////////////////////
00024 //                                                                      //
00025 // TDataSet                                                             //
00026 //                                                                      //
00027 // TDataSet class is to create a special compound object-container:     //
00028 //                                                                      //
00029 // ==================================================================== //
00030 //    TDataSet object ::= the "named" list of TDataSet objects          //
00031 // ==================================================================== //
00032 // where the "list" (the pointer to TList object) may contain no object //
00033 //                                                                      //
00034 //  TDataSet object has a back pointer to its "parent" TDataSet         //
00035 //  object, the "character" *name* and "character" *title*              //
00036 //                                                                      //
00037 //  The service this class does provide is to help the user to build    //
00038 //  and manage the hierarchy of his/her data but the data itself.       //
00039 //                                                                      //
00040 //  So it is not "Container" itself rather the basement (base class)    //
00041 //  to built the containers.                                            //
00042 //                                                                      //
00043 //  One may derive the custom container classes from TDataSet.          //
00044 //  See for example TObjectSet, TTable, TVolume, TFileSet               //
00045 //  These classes  derived from TDataSet:                               //
00046 //                                                                      //
00047 //   Class Name                                                         //
00048 //   ----------                                                         //
00049 //  TObjectSet::public TDataSet - is a container for TObject            //
00050 //  TTable::    public TDataSet - is a container for the array          //
00051 //                                    of any "plain" C-structure        //
00052 //  TNode::     public TDataSet - is a container for 3D objects         //
00053 //  TMaker::     public TDataSet - is a container for STAR "control"    //
00054 //                                    objects                           //
00055 //   etc etc                                                            //
00056 //                                                                      //
00057 //  TDataSet class is a base class to implement the directory-like      //
00058 //  data structures and maintain it via TDataSetIter class iterator     //
00059 //                                                                      //
00060 // TDataSet can be iterated using an iterator object (see TDataSetIter) //
00061 //            or by TDataSet::Pass method (see below)                   //
00062 //                                                                      //
00063 //  Terms:    Dataset       - any object from the list above            //
00064 //  =====     Member          is called "DataSet Member"                //
00065 //                                                                      //
00066 //          Structural      - the "Dataset Member" is its               //
00067 //            member          "Structural member" if its "back pointer" //
00068 //                            points to this object                     //
00069 //                                                                      //
00070 //           Dataset        - we will say this TDataSet object "OWNs"   //
00071 //            Owner           (or is an OWNER / PARENT of ) another     //
00072 //          (parent)          TDataSet object if the last one is its    //
00073 //                            "Structural Member"                       //
00074 //                                                                      //
00075 //          Associated      - If some object is not "Structural member" //
00076 //            member          of this object we will say it is an       //
00077 //                            "Associated Member" of this dataset       //
00078 //                                                                      //
00079 //           Orphan         - If some dataset is a member of NO other   //
00080 //           dataset          TDataSet object it is called an "orphan"  //
00081 //                            dataset object                            //
00082 //                                                                      //
00083 // - Any TDataSet object may be "Owned" by one and only one another     //
00084 //   TDataSet object if any.                                            //
00085 //                                                                      //
00086 // - Any TDataSet object can be the "Structural Member" of one and      //
00087 //   only one another TDataSet                                          //
00088 //                                                                      //
00089 // - Any TDataSet object may be an "Associated Member" for any number   //
00090 //   of other TDataSet objects if any                                   //
00091 //                                                                      //
00092 // - NAME issue:                                                        //
00093 //   Each "dataset member" is in possession of some "alpha-numerical"   //
00094 //   NAME as defined by TNamed class.                                   //
00095 //   The NAME may contain any "printable" symbols but "SLASH" - "/"     //
00096 //   The symbol "RIGHT SLASH" - "/" can not be used as any part of the  //
00097 //   "DataSet Member" NAME                                              //
00098 //    Any DataSet  can be found by its NAME with TDataSetIter object    //
00099 //                                                                      //
00100 // - TITLE issue:                                                       //
00101 //   Each "dataset member" is in possession of the "alpha-numerical"    //
00102 //   TITLE as defined by TNamed class. The meaning of the TITLE is      //
00103 //   reserved for the derived classes to hold there some indetification //
00104 //   that is special for that derived class.                            //
00105 //                                                                      //
00106 //   This means the user must be careful about  the "TDataSet           //
00107 //   NAME and TITLE since this may cause some "side effects" of the     //
00108 //   particular class functions                                         //
00109 //                                                                      //
00110 // - It is NOT required those all "DataSet Members" are in possession   //
00111 //   of the unique names, i.e. any number of "DataSet Members"          //
00112 //   may bear one and the same name                                     //
00113 //                                                                      //
00114 //   Actions:                                                           //
00115 //   ========                                                           //
00116 //   Create  DataSet is born either as "Orphan" or                      //
00117 //                                  as "Structural Member"              //
00118 //           of another TDataSet object                                 //
00119 //                                                                      //
00120 //   Add     One dataset can be included into another dataset.          //
00121 //           Upon adding:                                               //
00122 //           -  the "Orphan dataset" becomes "Structural Member"        //
00123 //           - "Structural Members" of another dataset becomes the      //
00124 //             "Associated Member" of this datatset                     //
00125 //                                                                      //
00126 //   Delete  - Upon deleting the "Structural Member":                   //
00127 //             - "REMOVES" itself  from the "Parent DataSet".           //
00128 //             - Its "Associated memberships" is not changed though     //
00129 //                                                                      //
00130 //              The last means the DataSet with the "Associated Members"//
00131 //              may contain a DIED pointers to unexisting "Associated"  //
00132 //              objects !!!                                             //
00133 //                                                                      //
00134 //  Further information is provided my the particular method            //
00135 //  descriptions.                                                       //
00136 //                                                                      //
00137 //  The TDataSet class has several methods to control object('s)        //
00138 //  memberships                                                         //
00139 //                                                                      //
00140 //////////////////////////////////////////////////////////////////////////
00141 
00142 TDataSet mainSet("DSMAIN");
00143 TDataSet *TDataSet::fgMainSet = &mainSet;
00144 
00145 ClassImp(TDataSet)
00146 
00147 //______________________________________________________________________________
00148 TDataSet::TDataSet(const Char_t *name, TDataSet *parent, Bool_t arrayFlag)
00149            : TNamed(name,"TDataSet"),fParent(0),fList(0)
00150 {
00151   //  cout << "ctor for " << GetName() << " - " << GetTitle() << endl;
00152    if (name && strchr(name,'/')) {
00153       Error("TDataSet::TDataSet","dataset name (%s) cannot contain a slash", name);
00154       return;
00155    }
00156    fList =0; fParent=0;
00157    if (arrayFlag) SetBit(kArray);
00158    if (parent) parent->Add(this);
00159 //   else AddMain(this);
00160 }
00161 
00162 //______________________________________________________________________________
00163 TDataSet *TDataSet::GetRealParent()
00164 {
00165    //return real parent
00166    TDataSet *p = GetParent();
00167    if (fgMainSet && p == fgMainSet) p = 0;
00168    return p;
00169 }
00170 //______________________________________________________________________________
00171 TDataSet::TDataSet(const TDataSet &pattern,EDataSetPass iopt):TNamed(pattern.GetName(),pattern.GetTitle()),
00172 fParent(0),fList(0)
00173 {
00174   //
00175   // Creates TDataSet (clone) with a topology similar with TDataSet *pattern
00176   //
00177   //  Parameters:
00178   //  -----------
00179   //  pattern        - the pattern dataset
00180   //  iopt = kStruct - clone only my structural links
00181   //         kAll    - clone all links
00182   //         kRefs   - clone only refs
00183   //         kMarked - clone marked (not implemented yet) only
00184   //
00185   //   All new-created sets become the structural ones anyway.
00186   //
00187   //  cout << "ctor for " << GetName() << " - " << GetTitle() << endl;
00188 
00189    TDataSet *set = 0;
00190    TDataSetIter next((TDataSet *)&pattern);
00191    Bool_t optsel = (iopt == kStruct);
00192    Bool_t optall = (iopt == kAll);
00193    while ((set = next())) {
00194 //              define the parent of the next set
00195       TDataSet *parent = set->GetParent();
00196       if ( optall || (optsel && parent == this) )
00197          Add((TDataSet *)(set->Clone()));
00198    }
00199 }
00200 
00201 //______________________________________________________________________________
00202 TDataSet::TDataSet(TNode &)
00203 {
00204    // This copy ctor has been depricated (left for thwe sake of the backweard compatibility)
00205    assert(0);
00206 }
00207 //______________________________________________________________________________
00208 TDataSet::~TDataSet()
00209 {
00210 //              cout << "Default destructor for " << GetName() << " - " << GetTitle() << endl;
00211    Shunt(0); Delete();
00212 }
00213 
00214 //______________________________________________________________________________
00215 void  TDataSet::MakeCollection()
00216 {
00217    // Create the internal container at once if any
00218    if (!fList)
00219       fList = TestBit(kArray) ? (TSeqCollection *)new TObjArray : (TSeqCollection *) new TList;
00220 }
00221 
00222 //______________________________________________________________________________
00223 void TDataSet::AddAt(TDataSet *dataset,Int_t idx)
00224 {
00225 //
00226 // Add TDataSet object at the "idx" position in ds
00227 // or at the end of the dataset
00228 // The final result is defined by either TList::AddAt or TObjArray::AddAt
00229 // methods
00230 //
00231    if (!dataset) return;
00232 
00233    MakeCollection();
00234 
00235    // Check whether this new child has got any parent yet
00236    if (!dataset->GetRealParent()) dataset->SetParent(this);
00237    fList->AddAt(dataset,idx);
00238 }
00239 
00240 //______________________________________________________________________________
00241 void TDataSet::AddAtAndExpand(TDataSet *dataset, Int_t idx)
00242 {
00243 //   !!!! Under construction !!!!!
00244 // Add TDataSet object at the "idx" position in ds
00245 // or at the end of the dataset
00246 // The final result is defined by either TList::AddAt or TObjArray::AddAt
00247 // methods
00248 //
00249    if (!dataset) return;
00250 
00251    MakeCollection();
00252 
00253    // Check whether this new child has got any parent yet
00254    if (!dataset->GetRealParent()) dataset->SetParent(this);
00255    if (TestBit(kArray)) ((TObjArray *) fList)->AddAtAndExpand(dataset,idx);
00256    else                  fList->AddAt(dataset,idx);
00257 }
00258 
00259 //______________________________________________________________________________
00260 void TDataSet::AddLast(TDataSet *dataset)
00261 {
00262 // Add TDataSet object at the end of the dataset list of this dataset
00263    if (!dataset) return;
00264 
00265    MakeCollection();
00266 
00267    // Check whether this new child has got any parent yet
00268    if (!dataset->GetRealParent()) dataset->SetParent(this);
00269    fList->AddLast(dataset);
00270 }
00271 
00272 //______________________________________________________________________________
00273 void TDataSet::AddFirst(TDataSet *dataset)
00274 {
00275  // Add TDataSet object at the beginning of the dataset list of this dataset
00276    if (!dataset) return;
00277 
00278    MakeCollection();
00279 
00280    // Check whether this new child has got any partent yet
00281    if (!dataset->GetRealParent()) dataset->SetParent(this);
00282    fList->AddFirst(dataset);
00283 }
00284 
00285 //______________________________________________________________________________
00286 void TDataSet::Browse(TBrowser *b)
00287 {
00288   // Browse this dataset (called by TBrowser).
00289    TDataSetIter next(this);
00290    TDataSet *obj;
00291    if (b)
00292       while ((obj = next())) b->Add(obj,obj->GetName());
00293 }
00294 
00295 //______________________________________________________________________________
00296 TObject *TDataSet::Clone(const char*) const
00297 {
00298    // the custom implementation fo the TObject::Clone
00299    return new TDataSet(*this);
00300 }
00301 
00302 //______________________________________________________________________________
00303 void TDataSet::Delete(Option_t *opt)
00304 {
00305 //
00306 // Delete - deletes the list of the TDataSet objects and all "Structural Members"
00307 //          as well
00308 //          This method doesn't affect the "Associated Members"
00309 //
00310    if(opt){/*unused*/}
00311 
00312 //      Delete list of the TDataSet
00313    TSeqCollection     *thisList = GetCollection();
00314    if (!thisList) return;
00315    fList = 0;
00316    TIter next(thisList);
00317    TDataSet *son = 0;
00318    //  Delete the "Structural Members" of this TDataSet only
00319    while ((son = (TDataSet *)next())) {
00320       if ( (!son->TObject::IsOnHeap()) || (this != son->TDataSet::GetParent()) ) continue;
00321       // mark the object is deleted from the TDataSet dtor or Delete method
00322       son->TDataSet::SetParent(0);
00323       if (son->TDataSet::Last()) { son->TDataSet::Delete(); }
00324       son->TObject::SetBit(kCanDelete);
00325       delete son;
00326    }
00327    //  Cleare list
00328    thisList->Clear("nodelete");
00329    delete thisList;
00330 }
00331 
00332 //______________________________________________________________________________
00333 TDataSet  *TDataSet::FindByPath(const Char_t *path) const
00334 {
00335    // Aliase for TDataSet::Find(const Char_t *path) method
00336    return Find(path);
00337 }
00338 
00339 //______________________________________________________________________________
00340 TDataSet *TDataSet::Find(const Char_t *path) const
00341 {
00342   //
00343   // Full description see: TDataSetIter::Find
00344   //
00345   // Note. This method is quite expansive.
00346   // ----- It is done to simplify the user's code when one wants to find ONLY object.
00347   //       If you need to find more then 1 object in this dataset,
00348   //       regard using TDataSetIter class yourself.
00349   //
00350    TDataSetIter next((TDataSet*)this);
00351    return next.Find(path);
00352 }
00353 
00354 //______________________________________________________________________________
00355 TDataSet *TDataSet::FindByName(const Char_t *name,const Char_t *path,Option_t *opt) const
00356 {
00357   //
00358   // Full description see: TDataSetIter::Find
00359   //
00360   // Note. This is method is quite expansive.
00361   // ----- It is done to simplify the user's code when one wants to find ONLY object.
00362   //       If you need to find more then 1 object in this dataset,
00363   //       regard using TDataSetIter class yourself.
00364   //
00365 
00366    TDataSetIter next((TDataSet*)this);
00367    return next.FindByName(name,path,opt);
00368 }
00369 
00370  //______________________________________________________________________________
00371 TDataSet *TDataSet::FindByTitle(const Char_t *title,const Char_t *path,Option_t *opt) const
00372 {
00373   //
00374   // Full description see: TDataSetIter::Find
00375   //
00376   // Note. This method is quite expansive.
00377   // ----- It is done to simplify the user's code when one wants to find ONLY object.
00378   //       If you need to find more then 1 object in this dataset,
00379   //       regard using TDataSetIter class yourself.
00380   //
00381    TDataSetIter next((TDataSet*)this);
00382    return next.FindByTitle(title,path,opt);
00383 }
00384 
00385 //______________________________________________________________________________
00386 TDataSet *TDataSet::First() const
00387 {
00388    //  Return the first object in the list. Returns 0 when list is empty.
00389    if (fList) return (TDataSet *)(fList->First());
00390    return 0;
00391 }
00392 
00393 //______________________________________________________________________________
00394 void TDataSet::AddMain(TDataSet *set)
00395 {
00396    //add data set to main data set
00397    
00398    if (fgMainSet && set) fgMainSet->AddFirst(set);
00399 }
00400 
00401 //______________________________________________________________________________
00402 TDataSet *TDataSet::GetMainSet() 
00403 {
00404    //return pointer to the main dataset
00405    
00406    return fgMainSet;
00407 }
00408 
00409 //______________________________________________________________________________
00410 TObject *TDataSet::GetObject() const
00411 {
00412    // The depricated method (left here for the sake of the backward compatibility)
00413    Print("***DUMMY GetObject***\n");
00414    return 0;
00415 }
00416 
00417 //______________________________________________________________________________
00418 TDataSet *TDataSet::Last() const
00419 {
00420    // Return the last object in the list. Returns 0 when list is empty.
00421    if (fList) return (TDataSet *)(fList->Last());
00422    return 0;
00423 }
00424 
00425 //______________________________________________________________________________
00426 TDataSet *TDataSet::Next() const
00427 {
00428    // Return the object next to this one in the parent structure
00429    // This convinient but time-consuming. Don't use it in the inner loops
00430    TDataSet *set = 0;
00431    TDataSet *parent = GetParent();
00432    if (parent) {
00433       TIter next(parent->GetCollection());
00434       // Find this object
00435       while ( (set = (TDataSet *)next()) && (set != this) ){}
00436       if (set) set = (TDataSet *)next();
00437    }
00438    return set;
00439 }
00440 
00441 //______________________________________________________________________________
00442 TDataSet *TDataSet::Prev() const
00443 {
00444    // Return the object that is previous to this one in the parent structure
00445    // This convinient but time-consuming. Don't use it in the inner loops
00446    TDataSet *prev = 0;
00447    TDataSet *set  = 0;
00448    TDataSet *parent = GetParent();
00449    if (parent) {
00450       TIter next(parent->GetCollection());
00451       // Find this object
00452       while ( (set = (TDataSet *)next()) && (set != this) ){prev = set;}
00453       if (!set) prev = 0;
00454    }
00455    return prev;
00456 }
00457 //______________________________________________________________________________
00458 void TDataSet::SetObject(TObject * /*obj*/)
00459 {
00460    // The depricated method (left here for the sake of the backward compatibility)
00461    Print("***DUMMY PutObject***\n");
00462 }
00463 
00464 //______________________________________________________________________________
00465 void  TDataSet::ls(Option_t *option) const
00466 {
00467  /////////////////////////////////////////////////////////////////////
00468  //                                                                 //
00469  //  ls(Option_t *option)                                           //
00470  //                                                                 //
00471  //    option       - defines the path to be listed                 //
00472  //           = "*" -  means print all levels                       //
00473  //                                                                 //
00474  /////////////////////////////////////////////////////////////////////
00475 
00476    if (option && !strcmp(option,"*")) ls(Int_t(0));
00477    else {
00478       TDataSet *set = 0;
00479       if (option && strlen(option) > 0) {
00480          TDataSetIter local((TDataSet*)this);
00481          set = local(option);
00482       } else
00483          set = (TDataSet*)this;
00484       if (set) set->ls(Int_t(1));
00485       else
00486          if (option) Warning("ls","Dataset <%s> not found",option);
00487    }
00488 }
00489 
00490 //______________________________________________________________________________
00491 void TDataSet::ls(Int_t depth) const
00492 {
00493  /////////////////////////////////////////////////////////////////////
00494  //                                                                 //
00495  //  ls(Int_t depth)                                                //
00496  //                                                                 //
00497  //  Prints the list of the this TDataSet.                          //
00498  //                                                                 //
00499  //  Parameter:                                                     //
00500  //  =========                                                      //
00501  //    Int_t depth >0 the number of levels to be printed            //
00502  //               =0 all levels will be printed                     //
00503  //            No par - ls() prints only level out                  //
00504  //                                                                 //
00505  /////////////////////////////////////////////////////////////////////
00506    PrintContents();
00507 
00508    if (!fList || depth == 1 ) return;
00509    if (!depth) depth = 99999;
00510 
00511    TIter next(fList);
00512    TDataSet *d=0;
00513    while ((d = (TDataSet *)next())) {
00514       TROOT::IncreaseDirLevel();
00515       d->ls(depth-1);
00516       TROOT::DecreaseDirLevel();
00517    }
00518 }
00519 //______________________________________________________________________________
00520 TDataSet *TDataSet::Instance() const
00521 {
00522  // apply the class default ctor to instantiate a new object of the same kind.
00523  // This is a base method to be overriden by the classes
00524  // derived from TDataSet (to support TDataSetIter::Mkdir for example)
00525    return instance();
00526 }
00527 
00528 //______________________________________________________________________________
00529 Bool_t TDataSet::IsThisDir(const Char_t *dirname,int len,int ignorecase) const
00530 {
00531    // Compare the name of the TDataSet with "dirname"
00532    // ignorercase flags indicates whether the comparision is case sensitive
00533 
00534    if (!ignorecase) {
00535       if (len<0) {return !strcmp (GetName(),dirname);
00536       } else     {return !strncmp(GetName(),dirname,len);}
00537    } else {
00538       const char *name = GetName();
00539       if (len==-1) len = strlen(dirname);
00540       for (int i=0;i<len;i++) { if ( tolower(name[i])!=tolower(dirname[i])) return 0;}
00541       return 1;
00542    }
00543 }
00544 
00545 //______________________________________________________________________________
00546 void TDataSet::MarkAll()
00547 {
00548    // Mark all members of this dataset
00549    Mark();
00550    TDataSetIter nextMark(this,0);
00551    TDataSet *set = 0;
00552    while ( (set = nextMark()) ) set->Mark();
00553 }
00554 
00555 //______________________________________________________________________________
00556 void TDataSet::UnMarkAll()
00557 {
00558    // UnMark all members of this dataset
00559    Mark(kMark,kReset);
00560    TDataSetIter nextMark(this,0);
00561    TDataSet *set = 0;
00562    while ( (set = nextMark()) ) set->Mark(kMark,kReset);
00563 }
00564 
00565 //______________________________________________________________________________
00566 void TDataSet::InvertAllMarks()
00567 {
00568   // Invert mark bit for all members of this dataset
00569    if (IsMarked()) Mark(kMark,kReset);
00570    else Mark();
00571    TDataSetIter nextMark(this,0);
00572    TDataSet *set = 0;
00573    while (( set = nextMark()) ) {
00574       if (set->IsMarked()) set->Mark(kMark,kReset);
00575       else set->Mark();
00576    }
00577 }
00578 
00579 //______________________________________________________________________________
00580 Bool_t TDataSet::IsEmpty() const
00581 {
00582    // return kTRUE if the "internal" collection has no member
00583    return First() ? kFALSE : kTRUE ;
00584 }
00585 
00586 //______________________________________________________________________________
00587 void TDataSet::PrintContents(Option_t *opt) const {
00588    // Callback method to complete ls() method recursive loop
00589    // This is to allow to sepoarate navigation and the custom invormation
00590    // in the derived classes (see; TTable::PrintContents for example
00591    if (opt) { /* no used */ }
00592    Printf("%3d - %s\t%s\n",TROOT::GetDirLevel(),(const char*)Path(),(char*)GetTitle());
00593 }
00594 
00595 //______________________________________________________________________________
00596 TString TDataSet::Path() const
00597 {
00598    // return the full path of this data set
00599    TString str;
00600    TDataSet *parent = GetParent();
00601    if (parent) {
00602       str = parent->Path();
00603       str += "/";
00604    }
00605    str +=  GetName();
00606    return str;
00607 }
00608 
00609 //______________________________________________________________________________
00610 void TDataSet::Remove(TDataSet *set)
00611 {
00612    // Remiove the "set" from this TDataSet
00613    if (fList && set) {
00614       if (set->GetParent() == this) set->SetParent(0);
00615       fList->Remove(set);
00616    }
00617 
00618 }
00619 
00620 //______________________________________________________________________________
00621 TDataSet  *TDataSet::RemoveAt(Int_t idx)
00622 {
00623    //
00624    // Remove object from the "idx" cell of this set and return
00625    // the pointer to the removed object if any
00626    //
00627    TDataSet *set = 0;
00628    if (fList) {
00629       set = (TDataSet *)fList->At(idx);
00630       fList->RemoveAt(idx);
00631       if (set && (set->GetParent() == this) ) set->SetParent(0);
00632    }
00633    return set;
00634 }
00635 
00636 //______________________________________________________________________________
00637 TDataSet::EDataSetPass TDataSet::Pass(EDataSetPass ( *callback)(TDataSet *),Int_t depth)
00638 {
00639  /////////////////////////////////////////////////////////////////////
00640  //                                                                 //
00641  // Pass (callback,depth)                                           //
00642  //                                                                 //
00643  // Calls callback(this) for all datasets those recursively         //
00644  //                                                                 //
00645  //  Parameter:                                                     //
00646  //  =========                                                      //
00647  //    Int_t depth >0 the number of levels to be passed             //
00648  //                =0 all levels will be passed                     //
00649  //                                                                 //
00650  //  Return (this value mast be returned by the user's callback):   //
00651  //  ======                                                         //
00652  //  kContinue - continue passing                                   //
00653  //  kPrune    - stop passing the current branch, go to the next one//
00654  //  kUp       - stop passing, leave the current branch,            //
00655  //              return to previous level and continue              //
00656  //  kStop     - stop passing, leave all braches                    //
00657  //                                                                 //
00658  /////////////////////////////////////////////////////////////////////
00659 
00660    if (!callback) return kStop;
00661 
00662    EDataSetPass condition = callback(this);
00663 
00664    if (condition == kContinue){
00665       if (fList && depth != 1 ) {
00666          TIter next(fList);
00667          TDataSet *d=0;
00668          while ( (d = (TDataSet *)next()) ) {
00669             condition = d->Pass(callback, depth == 0 ? 0 : --depth);
00670             if (condition == kStop || condition == kUp) break;
00671          }
00672       }
00673    }
00674    return condition==kUp ? kContinue:condition;
00675 }
00676 
00677 //______________________________________________________________________________
00678 TDataSet::EDataSetPass TDataSet::Pass(EDataSetPass ( *callback)(TDataSet *,void*),void *user,Int_t depth)
00679 {
00680  /////////////////////////////////////////////////////////////////////
00681  //                                                                 //
00682  // Pass (callback,user,depth)                                      //
00683  //                                                                 //
00684  // Calls callback(this,user) for all datasets those recursively    //
00685  //                                                                 //
00686  //  Parameter:                                                     //
00687  //  =========                                                      //
00688  //    Int_t depth >0 the number of levels to be passed             //
00689  //                =0 all levels will be passed                     //
00690  //                                                                 //
00691  //  Return (this value mast be returned by the user's callback):   //
00692  //  ======                                                         //
00693  //  kContinue - continue passing                                   //
00694  //  kPrune    - stop passing the current branch, go to the next one//
00695  //  kUp       - stop passing, leave the current branch,            //
00696  //              return to previous level and continue              //
00697  //  kStop     - stop passing, leave all braches                    //
00698  //                                                                 //
00699  /////////////////////////////////////////////////////////////////////
00700 
00701    if (!callback) return kStop;
00702 
00703    EDataSetPass condition = callback(this,user);
00704 
00705    if (condition == kContinue){
00706       if (fList && depth != 1 ) {
00707          TIter next(fList);
00708          TDataSet *d=0;
00709          while ((d = (TDataSet *)next())) {
00710             condition = d->Pass(callback, user, depth == 0 ? 0 : --depth);
00711             if (condition == kStop) break;
00712             if (condition == kUp  ) break;
00713          }
00714       }
00715    }
00716    return (condition==kUp) ? kContinue:condition;
00717 }
00718 
00719 //______________________________________________________________________________
00720 Int_t TDataSet::Purge(Option_t *)
00721 {
00722 //
00723 // Purge  - deletes all "dummy" "Structural Members" those are not ended
00724 //          up with some dataset with data inside (those return HasData() = 0)
00725 //
00726 // Purge does affect only the "Structural Members" and doesn't "Associated" ones
00727 //
00728 
00729    if (!fList) return 0;
00730    TIter next(fList);
00731    TDataSet *son = 0;
00732    // Purge "Structural Members" only
00733    TList garbage;
00734    while ((son = (TDataSet *)next())) {
00735       if (this == son->GetParent()) continue;
00736       //   mark the object is deleted from the TDataSet dtor
00737       son->Purge();
00738       if (son->HasData() || son->GetListSize()) continue;
00739       delete son;
00740    }
00741    return 0;
00742 }
00743 
00744 //______________________________________________________________________________
00745 void  TDataSet::SetParent(TDataSet *parent)
00746 {
00747 //
00748 //  Break the "parent" relationship with the current object parent if present
00749 //  parent != 0   Makes this object the "Structural Member"
00750 //                of the "parent" dataset
00751 //          = 0   Makes this object the "pure Associator", i.e it makes this
00752 //                object the "Structural Member" of NO other TDataSet
00753 //
00754    fParent = parent;
00755 }
00756 
00757 //______________________________________________________________________________
00758 void TDataSet::SetWrite()
00759 {
00760  // One should not use this method but TDataSet::Write instead
00761  // This method os left here for the sake of the backward compatibility
00762  // To Write object first we should temporary break the
00763  // the backward fParent pointer (otherwise ROOT follows this links
00764  // and will pull fParent out too.
00765  //
00766    Write();
00767 }
00768 
00769 //______________________________________________________________________________
00770 void TDataSet::Shunt(TDataSet *newParent)
00771 {
00772   //
00773   //  Remove the object from the original and add it to dataset
00774   //  TDataSet dataset   != 0  -  Make this object the "Structural Member"
00775   //                                of "dataset"
00776   //                        = 0  -  Make this object "Orphan"
00777   //
00778    if (fParent)   fParent->Remove(this);
00779    if (newParent) newParent->Add(this);
00780 }
00781 
00782 //______________________________________________________________________________
00783 void TDataSet::Update(TDataSet* set,UInt_t opt)
00784 {
00785 //
00786 // Update this TDataSet with "set"
00787 //
00788 // ATTENTION !!!
00789 // ---------
00790 // This method changes the parent relationships of the input "set"
00791 //
00792    if(opt){/*unused*/}
00793    if(!set) return;
00794 
00795    SetTitle(set->GetTitle());
00796    TDataSetIter nextnew(set);
00797    TDataSet *newset = 0;
00798    while((newset = nextnew())) {
00799       Bool_t found = kFALSE;
00800       //              Check whether this has the list of the sons
00801       if (fList) {
00802          TIter nextold(fList);
00803          const Char_t *newname = newset->GetName();
00804          TDataSet *oldset = 0;
00805          while ( ((oldset = (TDataSet *)nextold())!=0) && !found) {
00806             // if the "new" set does contain the dataset
00807             // with the same name as ours update it too
00808             // (We do not update itself (oldset == newset)
00809             if ( (oldset != newset) && oldset->IsThisDir(newname) ) {
00810                oldset->Update(newset);
00811                found = kTRUE;
00812             }
00813          }
00814       }
00815       // If the new "set" contains some new dataset with brand-new name
00816       // move it into the our dataset and remove it from its old location
00817       if (!found) newset->Shunt(this);
00818    }
00819 }
00820 
00821 //______________________________________________________________________________
00822 void TDataSet::Update()
00823 {
00824  //
00825  //  Update()
00826  //
00827  //  Recursively updates all tables for all nested datasets
00828  //  in inverse order
00829  //
00830 
00831    TDataSetIter next(this);
00832    TDataSet *set = 0;
00833    while(( set = next())) set->Update();
00834 }
00835 
00836 //______________________________________________________________________________
00837 void TDataSet::Sort()
00838 {
00839    // Sort recursively all members of the TDataSet with TList::Sort method
00840    TDataSetIter next(this,0);
00841    TDataSet *ds;
00842    TList *list;
00843    while ((ds=next())) {
00844       list = ds->GetList();
00845       if (!list) continue;
00846       list->Sort(); ds->Sort();
00847    }
00848 }
00849 
00850 //______________________________________________________________________________
00851 Int_t TDataSet::Write(const char *name, Int_t option, Int_t bufsize)
00852 {
00853  //
00854  // To Write object first we should temporary break the
00855  // the backward fParent pointer (otherwise ROOT follows this links
00856  // and will pull fParent out too.
00857  //
00858    TDataSet *saveParent = fParent; // GetParent();
00859    fParent = 0;
00860    Int_t nbytes = TObject::Write(name,option, bufsize);
00861    fParent = saveParent;
00862    return nbytes;
00863 }
00864 
00865 //______________________________________________________________________________
00866 Int_t TDataSet::Write(const char *name, Int_t option, Int_t bufsize) const
00867 {
00868  //
00869  // To Write object first we should temporary break the
00870  // the backward fParent pointer (otherwise ROOT follows this links
00871  // and will pull fParent out too.
00872  //
00873    TDataSet *saveParent = fParent; // GetParent();
00874    const_cast<TDataSet*>(this)->fParent = 0;
00875    Int_t nbytes = TObject::Write(name,option, bufsize);
00876    const_cast<TDataSet*>(this)->fParent = saveParent;
00877    return nbytes;
00878 }

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