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