Logo ROOT  
Reference Guide
TFolder.cxx
Go to the documentation of this file.
1// @(#)root/base:$Id$
2// Author: Rene Brun 02/09/2000
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12
13/** \class TFolder
14\ingroup Base
15
16A TFolder object is a collection of objects and folders.
17Folders have a name and a title and are identified in the folder hierarchy
18by a "Unix-like" naming mechanism. The root of all folders is //root.
19New folders can be dynamically added or removed to/from a folder.
20The folder hierarchy can be visualized via the TBrowser.
21
22\image html base_browser.png
23
24The Root folders hierarchy can be seen as a whiteboard where objects
25are posted. Other classes/tasks can access these objects by specifying
26only a string pathname. This whiteboard facility greatly improves the
27modularity of an application, minimizing the class relationship problem
28that penalizes large applications.
29
30Pointers are efficient to communicate between classes.
31However, one has interest to minimize direct coupling between classes
32in the form of direct pointers. One better uses the naming and search
33service provided by the Root folders hierarchy. This makes the classes
34loosely coupled and also greatly facilitates I/O operations.
35In a client/server environment, this mechanism facilitates the access
36to any kind of object in //root stores running on different processes.
37
38A TFolder is created by invoking the TFolder constructor. It is placed
39inside an existing folder via the TFolder::AddFolder method.
40One can search for a folder or an object in a folder using the FindObject
41method. FindObject analyses the string passed as its argument and searches
42in the hierarchy until it finds an object or folder matching the name.
43
44When a folder is deleted, its reference from the parent folder and
45possible other folders is deleted.
46
47If a folder has been declared the owner of its objects/folders via
48TFolder::SetOwner, then the contained objects are deleted when the
49folder is deleted. By default, a folder does not own its contained objects.
50
51NOTE that folder ownership can be set
52 - via TFolder::SetOwner
53 - or via TCollection::SetOwner on the collection specified to TFolder::AddFolder
54
55Standard Root objects are automatically added to the folder hierarchy.
56For example, the following folders exist:
57 //root/Files with the list of currently connected Root files
58 //root/Classes with the list of active classes
59 //root/Geometries with active geometries
60 //root/Canvases with the list of active canvases
61 //root/Styles with the list of graphics styles
62 //root/Colors with the list of active colors
63
64For example, if a file "myFile.root" is added to the list of files, one can
65retrieve a pointer to the corresponding TFile object with a statement like:
66~~~ {.cpp}
67 TFile *myFile = (TFile*)gROOT->FindObject("//root/Files/myFile.root");
68~~~
69The above statement can be abbreviated to:
70~~~ {.cpp}
71 TFile *myFile = (TFile*)gROOT->FindObject("/Files/myFile.root");
72~~~
73or even to:
74~~~ {.cpp}
75 TFile *myFile = (TFile*)gROOT->FindObjectAny("myFile.root");
76~~~
77In this last case, the TROOT::FindObjectAny function will scan the folder hierarchy
78starting at //root and will return the first object named "myFile.root".
79
80Because a string-based search mechanism is expensive, it is recommended
81to save the pointer to the object as a class member or local variable
82if this pointer is used frequently or inside loops.
83*/
84
85#include <iostream>
86#include "Strlen.h"
87#include "strlcpy.h"
88#include "TFolder.h"
89#include "TBrowser.h"
90#include "TList.h"
91#include "TROOT.h"
92#include "TClass.h"
93#include "TError.h"
94#include "TRegexp.h"
95
96static const char *gFolderD[64];
97static Int_t gFolderLevel = -1;
98static char gFolderPath[512];
99
100enum { kOwnFolderList = BIT(15) };
101
103
104////////////////////////////////////////////////////////////////////////////////
105/// Default constructor used by the Input functions.
106///
107/// This constructor should not be called by a user directly.
108/// The normal way to create a folder is by calling TFolder::AddFolder.
109
111{
112 fFolders = nullptr;
114}
115
116////////////////////////////////////////////////////////////////////////////////
117/// Create a normal folder.
118/// Use Add or AddFolder to add objects or folders to this folder.
119
120TFolder::TFolder(const char *name, const char *title) : TNamed(name,title)
121{
122 fFolders = new TList();
125}
126
127////////////////////////////////////////////////////////////////////////////////
128/// Folder destructor. Remove all objects from its lists and delete
129/// all its sub folders.
130
132{
134
135 if (fFolders) {
136 if (fFolders->IsOwner()) {
137 fFolders->Delete();
138 }
139 if (TestBit(kOwnFolderList)) {
140 TObjLink *iter = ((TList*)fFolders)->FirstLink();
141 while (iter) {
142 TObject *obj = iter->GetObject();
143 TObjLink *next = iter->Next();
144 if (obj && obj->IsA() == TFolder::Class()) {
145 ((TList*)fFolders)->Remove(iter);
146 delete obj;
147 }
148 iter = next;
149 }
150 fFolders->Clear("nodelete");
152 }
153 }
154
156
157 if (gDebug)
158 std::cerr << "TFolder dtor called for "<< GetName() << std::endl;
159}
160
161////////////////////////////////////////////////////////////////////////////////
162/// Add object to this folder. obj must be a TObject or a TFolder.
163
165{
166 if (obj == nullptr || fFolders == nullptr) return;
167 obj->SetBit(kMustCleanup);
168 fFolders->Add(obj);
169}
170
171////////////////////////////////////////////////////////////////////////////////
172/// Create a new folder and add it to the list of folders of this folder,
173/// return a pointer to the created folder.
174/// Note that a folder can be added to several folders.
175///
176/// If collection is non NULL, the pointer fFolders is set to the existing
177/// collection, otherwise a default collection (Tlist) is created.
178/// Note that the folder name cannot contain slashes.
179
180TFolder *TFolder::AddFolder(const char *name, const char *title, TCollection *collection)
181{
182 if (strchr(name,'/')) {
183 ::Error("TFolder::TFolder","folder name cannot contain a slash: %s", name);
184 return nullptr;
185 }
186 if (strlen(GetName()) == 0) {
187 ::Error("TFolder::TFolder","folder name cannot be \"\"");
188 return nullptr;
189 }
190 TFolder *folder = new TFolder();
191 folder->SetName(name);
192 folder->SetTitle(title);
193 if (!fFolders) {
194 fFolders = new TList(); //only true when gROOT creates its 1st folder
196 }
197 fFolders->Add(folder);
198
199 if (collection) {
200 folder->fFolders = collection;
201 } else {
202 folder->fFolders = new TList();
203 folder->SetBit(kOwnFolderList);
204 }
205 return folder;
206}
207
208////////////////////////////////////////////////////////////////////////////////
209/// Browse this folder.
210
212{
213 if (fFolders) fFolders->Browse(b);
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Delete all objects from a folder list.
218
220{
222}
223
224////////////////////////////////////////////////////////////////////////////////
225/// Return the full pathname corresponding to subpath name if the node is
226/// gROOT->GetRootFolder() and return a relative path otherwise.
227/// The returned path will be re-used by the next call to FindFullPathName().
228
229const char *TFolder::FindFullPathName(const char *name) const
230{
231 TObject *obj = FindObject(name);
232 if (obj || !fFolders) {
233 gFolderLevel++;
235 if (strcmp(gFolderD[0],"root")==0) {
236 strlcpy(gFolderPath,"//root/", sizeof(gFolderPath));
237 } else {
238 gFolderPath[0] = '\0';
239 }
240 for (Int_t l = 1; l<=gFolderLevel;l++) {
241 strlcat(gFolderPath, gFolderD[l], sizeof(gFolderPath));
242 strlcat(gFolderPath, "/", sizeof(gFolderPath));
243 }
244 strlcat(gFolderPath,name, sizeof(gFolderPath));
245 gFolderLevel = -1;
246 return gFolderPath;
247 }
248 if (name[0] == '/') return nullptr;
249 TIter next(fFolders);
250 TFolder *folder;
251 const char *found;
252 gFolderLevel++;
254 while ((obj=next())) {
255 // For a TClass object, InheritsFrom does not check the inheritance of
256 // the object but the inheritance of the class described by the object,
257 // so we need to explicitly call IsA
258 if (obj->IsA()->InheritsFrom(TClass::Class())) continue;
259 // For any other object IsA is called by InheritsFrom
260 if (!obj->InheritsFrom(TFolder::Class())) continue;
261 folder = (TFolder*)obj;
262 found = folder->FindFullPathName(name);
263 if (found) return found;
264 }
265 gFolderLevel--;
266 return nullptr;
267}
268
269
270////////////////////////////////////////////////////////////////////////////////
271/// Return the full pathname corresponding to subpath name.
272/// The returned path will be re-used by the next call to FindFullPathName().
273
274const char *TFolder::FindFullPathName(const TObject *) const
275{
276 Error("FindFullPathname","Not yet implemented");
277 return nullptr;
278}
279
280////////////////////////////////////////////////////////////////////////////////
281/// Find object in an folder.
282
284{
285 Error("FindObject","Not yet implemented");
286 return nullptr;
287}
288
289////////////////////////////////////////////////////////////////////////////////
290/// Search object identified by name in the tree of folders inside
291/// this folder.
292/// Name may be of the forms:
293///
294/// A. Specify a full pathname starting at the top ROOT folder
295/// //root/xxx/yyy/name
296///
297/// B. Specify a pathname starting with a single slash. //root is assumed
298/// /xxx/yyy/name
299///
300/// C. Specify a pathname relative to this folder
301/// xxx/yyy/name
302/// name
303
305{
306 if (!fFolders || !name) return nullptr;
307 if (name[0] == '/') {
308 if (name[1] == '/') {
309 if (!strstr(name,"//root/")) return nullptr;
310 return gROOT->GetRootFolder()->FindObject(name+7);
311 } else {
312 return gROOT->GetRootFolder()->FindObject(name+1);
313 }
314 }
315 Int_t nch = strlen(name);
316 char csname[128];
317 char *cname = csname;
318 Int_t len = sizeof(csname);
319 if (nch >= len) {
320 len = nch+1;
321 cname = new char[len];
322 }
323 strlcpy(cname, name, len);
324 TObject *ret = nullptr;
325 char *slash = strchr(cname,'/');
326 if (slash) {
327 *slash = 0;
328 if (TObject *obj = fFolders->FindObject(cname))
329 ret = obj->FindObject(slash+1);
330 } else {
331 ret = fFolders->FindObject(cname);
332 }
333 if (cname != csname)
334 delete [] cname;
335 return ret;
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Return a pointer to the first object with name starting at this folder.
340
342{
343 TObject *obj = FindObject(name);
344 if (obj || !fFolders) return obj;
345
346 //if (!obj->InheritsFrom(TFolder::Class())) continue;
347 if (name[0] == '/') return nullptr;
348 TIter next(fFolders);
349 TFolder *folder;
350 TObject *found;
352 while ((obj=next())) {
353 if (!obj->InheritsFrom(TFolder::Class())) continue;
354 if (obj->IsA() == TClass::Class()) continue;
355 folder = (TFolder*)obj;
356 found = folder->FindObjectAny(name);
357 if (found) return found;
358 }
359 return nullptr;
360}
361
362////////////////////////////////////////////////////////////////////////////////
363/// Folder ownership has been set via
364/// - TFolder::SetOwner
365/// - TCollection::SetOwner on the collection specified to TFolder::AddFolder
366
368{
369 if (!fFolders) return kFALSE;
370 return fFolders->IsOwner();
371}
372
373////////////////////////////////////////////////////////////////////////////////
374/// List folder contents.
375///
376/// If option contains "dump", the Dump function of contained objects is called.
377///
378/// If option contains "print", the Print function of contained objects is called.
379///
380/// By default the ls function of contained objects is called.
381///
382/// Indentation is used to identify the folder tree.
383///
384/// The if option contains a `<regexp>` it be used to match the name of the objects.
385
387{
388 if (!fFolders) return;
390 std::cout <<ClassName()<<"*\t\t"<<GetName()<<"\t"<<GetTitle()<<std::endl;
392
393 TString opt = option;
394 Ssiz_t dump = opt.Index("dump", 0, TString::kIgnoreCase);
395 if (dump != kNPOS)
396 opt.Remove(dump, 4);
397 Ssiz_t print = opt.Index("print", 0, TString::kIgnoreCase);
398 if (print != kNPOS)
399 opt.Remove(print, 5);
400 opt = opt.Strip(TString::kBoth);
401 if (opt == "")
402 opt = "*";
403 TRegexp re(opt, kTRUE);
404
405 TObject *obj;
406 TIter nextobj(fFolders);
407 while ((obj = (TObject *) nextobj())) {
408 TString s = obj->GetName();
409 if (s.Index(re) == kNPOS) continue;
410 if (dump != kNPOS)
411 obj->Dump();
412 if (print != kNPOS)
413 obj->Print(option);
414 obj->ls(option);
415 }
417}
418
419////////////////////////////////////////////////////////////////////////////////
420/// Return occurence number of object in the list of objects of this folder.
421/// The function returns the number of objects with the same name as object
422/// found in the list of objects in this folder before object itself.
423/// If only one object is found, return 0.
424
425Int_t TFolder::Occurence(const TObject *object) const
426{
427 Int_t n = 0;
428 if (!fFolders) return 0;
429 TIter next(fFolders);
430 TObject *obj;
431 while ((obj=next())) {
432 if (strcmp(obj->GetName(),object->GetName()) == 0) n++;
433 }
434 if (n <=1) return n-1;
435 n = 0;
436 next.Reset();
437 while ((obj=next())) {
438 if (strcmp(obj->GetName(),object->GetName()) == 0) n++;
439 if (obj == object) return n;
440 }
441 return 0;
442}
443
444////////////////////////////////////////////////////////////////////////////////
445/// Recursively remove object from a folder.
446
448{
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Remove object from this folder. obj must be a TObject or a TFolder.
454
456{
457 if (obj == nullptr || fFolders == nullptr) return;
458 fFolders->Remove(obj);
459}
460
461////////////////////////////////////////////////////////////////////////////////
462/// Save all objects in this folder in filename.
463/// Each object in this folder will have a key in the file where the name of
464/// the key will be the name of the object.
465
466void TFolder::SaveAs(const char *filename, Option_t *option) const
467{
468 if (gDirectory) gDirectory->SaveObjectAs(this,filename,option);
469}
470
471////////////////////////////////////////////////////////////////////////////////
472/// Set ownership.
473/// If the folder is declared owner, when the folder is deleted, all
474/// the objects added via TFolder::Add are deleted via TObject::Delete,
475/// otherwise TObject::Clear is called.
476///
477/// NOTE that folder ownership can be set:
478/// - via TFolder::SetOwner
479/// - or via TCollection::SetOwner on the collection specified to TFolder::AddFolder
480
482{
483 if (!fFolders) fFolders = new TList();
484 fFolders->SetOwner(owner);
485}
#define SafeDelete(p)
Definition: RConfig.hxx:534
const Ssiz_t kNPOS
Definition: RtypesCore.h:124
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define BIT(n)
Definition: Rtypes.h:85
#define ClassImp(name)
Definition: Rtypes.h:375
#define gDirectory
Definition: TDirectory.h:348
@ kOwnFolderList
Definition: TFolder.cxx:100
static const char * gFolderD[64]
Definition: TFolder.cxx:96
static Int_t gFolderLevel
Definition: TFolder.cxx:97
static char gFolderPath[512]
Definition: TFolder.cxx:98
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
char name[80]
Definition: TGX11.cxx:110
Int_t gDebug
Definition: TROOT.cxx:585
#define gROOT
Definition: TROOT.h:404
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
static TClass * Class()
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4862
Collection abstract base class.
Definition: TCollection.h:65
virtual TObject * Remove(TObject *obj)=0
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
static void EmptyGarbageCollection()
Do the garbage collection.
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
void Browse(TBrowser *b) override
Browse this collection (called by TBrowser).
virtual void Add(TObject *obj)=0
Bool_t IsOwner() const
Definition: TCollection.h:190
TObject * FindObject(const char *name) const override
Find an object in this collection using its name.
void Delete(Option_t *option="") override=0
Delete this object.
void Clear(Option_t *option="") override=0
static void StartGarbageCollection()
Set up for garbage collection.
A TFolder object is a collection of objects and folders.
Definition: TFolder.h:30
void RecursiveRemove(TObject *obj) override
Recursively remove object from a folder.
Definition: TFolder.cxx:447
void Browse(TBrowser *b) override
Browse this folder.
Definition: TFolder.cxx:211
TFolder()
Default constructor used by the Input functions.
Definition: TFolder.cxx:110
virtual TObject * FindObjectAny(const char *name) const
Return a pointer to the first object with name starting at this folder.
Definition: TFolder.cxx:341
TFolder * AddFolder(const char *name, const char *title, TCollection *collection=nullptr)
Create a new folder and add it to the list of folders of this folder, return a pointer to the created...
Definition: TFolder.cxx:180
virtual void Add(TObject *obj)
Add object to this folder. obj must be a TObject or a TFolder.
Definition: TFolder.cxx:164
void Clear(Option_t *option="") override
Delete all objects from a folder list.
Definition: TFolder.cxx:219
virtual ~TFolder()
Folder destructor.
Definition: TFolder.cxx:131
TObject * FindObject(const char *name) const override
Search object identified by name in the tree of folders inside this folder.
Definition: TFolder.cxx:304
void ls(Option_t *option="") const override
List folder contents.
Definition: TFolder.cxx:386
void SaveAs(const char *filename="", Option_t *option="") const override
Save all objects in this folder in filename.
Definition: TFolder.cxx:466
virtual const char * FindFullPathName(const char *name) const
Return the full pathname corresponding to subpath name if the node is gROOT->GetRootFolder() and retu...
Definition: TFolder.cxx:229
Bool_t fIsOwner
Definition: TFolder.h:34
virtual void SetOwner(Bool_t owner=kTRUE)
Set ownership.
Definition: TFolder.cxx:481
Bool_t IsOwner() const
Folder ownership has been set via.
Definition: TFolder.cxx:367
virtual Int_t Occurence(const TObject *obj) const
Return occurence number of object in the list of objects of this folder.
Definition: TFolder.cxx:425
static TClass * Class()
TCollection * fFolders
Definition: TFolder.h:33
virtual void Remove(TObject *obj)
Remove object from this folder. obj must be a TObject or a TFolder.
Definition: TFolder.cxx:455
void Reset()
Definition: TCollection.h:254
A doubly linked list.
Definition: TList.h:38
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition: TNamed.h:48
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
virtual void Dump() const
Dump contents of object on stdout.
Definition: TObject.cxx:268
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:323
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:893
virtual TClass * IsA() const
Definition: TObject.h:230
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition: TObject.cxx:552
virtual void ls(Option_t *option="") const
The ls function lists the contents of a class on stdout.
Definition: TObject.cxx:494
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition: TObject.h:60
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition: TROOT.cxx:2799
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition: TROOT.cxx:2807
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition: TROOT.cxx:2692
Regular expression class.
Definition: TRegexp.h:31
Basic string class.
Definition: TString.h:136
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1131
@ kBoth
Definition: TString.h:267
@ kIgnoreCase
Definition: TString.h:268
TString & Remove(Ssiz_t pos)
Definition: TString.h:673
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:639
const Int_t n
Definition: legend1.C:16
static constexpr double s
TCanvas * slash()
Definition: slash.C:1
auto * l
Definition: textangle.C:4