Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
104
105////////////////////////////////////////////////////////////////////////////////
106/// Default constructor used by the Input functions.
107///
108/// This constructor should not be called by a user directly.
109/// The normal way to create a folder is by calling TFolder::AddFolder.
110
112{
113 fFolders = nullptr;
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Create a normal folder.
119/// Use Add or AddFolder to add objects or folders to this folder.
120
121TFolder::TFolder(const char *name, const char *title) : TNamed(name,title)
122{
123 fFolders = new TList();
126}
127
128////////////////////////////////////////////////////////////////////////////////
129/// Folder destructor. Remove all objects from its lists and delete
130/// all its sub folders.
131
133{
135
136 if (fFolders) {
137 if (fFolders->IsOwner()) {
138 fFolders->Delete();
139 }
140 if (TestBit(kOwnFolderList)) {
141 TObjLink *iter = ((TList*)fFolders)->FirstLink();
142 while (iter) {
143 TObject *obj = iter->GetObject();
144 TObjLink *next = iter->Next();
145 if (obj && obj->IsA() == TFolder::Class()) {
146 ((TList*)fFolders)->Remove(iter);
147 delete obj;
148 }
149 iter = next;
150 }
151 fFolders->Clear("nodelete");
153 }
154 }
155
157
158 if (gDebug)
159 std::cerr << "TFolder dtor called for "<< GetName() << std::endl;
160}
161
162////////////////////////////////////////////////////////////////////////////////
163/// Add object to this folder. obj must be a TObject or a TFolder.
164
166{
167 if (obj == nullptr || fFolders == nullptr) return;
168 obj->SetBit(kMustCleanup);
169 fFolders->Add(obj);
170}
171
172////////////////////////////////////////////////////////////////////////////////
173/// Create a new folder and add it to the list of folders of this folder,
174/// return a pointer to the created folder.
175/// Note that a folder can be added to several folders.
176///
177/// If collection is non NULL, the pointer fFolders is set to the existing
178/// collection, otherwise a default collection (Tlist) is created.
179/// Note that the folder name cannot contain slashes.
180
181TFolder *TFolder::AddFolder(const char *name, const char *title, TCollection *collection)
182{
183 if (strchr(name,'/')) {
184 ::Error("TFolder::TFolder","folder name cannot contain a slash: %s", name);
185 return nullptr;
186 }
187 if (strlen(GetName()) == 0) {
188 ::Error("TFolder::TFolder","folder name cannot be \"\"");
189 return nullptr;
190 }
191 TFolder *folder = new TFolder();
192 folder->SetName(name);
193 folder->SetTitle(title);
194 if (!fFolders) {
195 fFolders = new TList(); //only true when gROOT creates its 1st folder
197 }
199
200 if (collection) {
201 folder->fFolders = collection;
202 } else {
203 folder->fFolders = new TList();
204 folder->SetBit(kOwnFolderList);
205 }
206 return folder;
207}
208
209////////////////////////////////////////////////////////////////////////////////
210/// Browse this folder.
211
213{
214 if (fFolders) fFolders->Browse(b);
215}
216
217////////////////////////////////////////////////////////////////////////////////
218/// Delete all objects from a folder list.
219
224
225////////////////////////////////////////////////////////////////////////////////
226/// Return the full pathname corresponding to subpath name if the node is
227/// gROOT->GetRootFolder() and return a relative path otherwise.
228/// The returned path will be re-used by the next call to FindFullPathName().
229
230const char *TFolder::FindFullPathName(const char *name) const
231{
232 TObject *obj = FindObject(name);
233 if (obj || !fFolders) {
234 gFolderLevel++;
236 if (strcmp(gFolderD[0],"root")==0) {
237 strlcpy(gFolderPath,"//root/", sizeof(gFolderPath));
238 } else {
239 gFolderPath[0] = '\0';
240 }
241 for (Int_t l = 1; l<=gFolderLevel;l++) {
243 strlcat(gFolderPath, "/", sizeof(gFolderPath));
244 }
246 gFolderLevel = -1;
247 return gFolderPath;
248 }
249 if (name[0] == '/') return nullptr;
250 TIter next(fFolders);
252 const char *found;
253 gFolderLevel++;
255 while ((obj=next())) {
256 // For a TClass object, InheritsFrom does not check the inheritance of
257 // the object but the inheritance of the class described by the object,
258 // so we need to explicitly call IsA
259 if (obj->IsA()->InheritsFrom(TClass::Class())) continue;
260 // For any other object IsA is called by InheritsFrom
261 if (!obj->InheritsFrom(TFolder::Class())) continue;
262 folder = (TFolder*)obj;
263 found = folder->FindFullPathName(name);
264 if (found) return found;
265 }
266 gFolderLevel--;
267 return nullptr;
268}
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Return the full pathname corresponding to subpath name.
273/// The returned path will be re-used by the next call to FindFullPathName().
274
275const char *TFolder::FindFullPathName(const TObject *) const
276{
277 Error("FindFullPathname","Not yet implemented");
278 return nullptr;
279}
280
281////////////////////////////////////////////////////////////////////////////////
282/// Find object in an folder.
283
285{
286 Error("FindObject","Not yet implemented");
287 return nullptr;
288}
289
290////////////////////////////////////////////////////////////////////////////////
291/// Search object identified by name in the tree of folders inside
292/// this folder.
293/// Name may be of the forms:
294///
295/// A. Specify a full pathname starting at the top ROOT folder
296/// //root/xxx/yyy/name
297///
298/// B. Specify a pathname starting with a single slash. //root is assumed
299/// /xxx/yyy/name
300///
301/// C. Specify a pathname relative to this folder
302/// xxx/yyy/name
303/// name
304
306{
307 if (!fFolders || !name) return nullptr;
308 if (name[0] == '/') {
309 if (name[1] == '/') {
310 if (!strstr(name,"//root/")) return nullptr;
311 return gROOT->GetRootFolder()->FindObject(name+7);
312 } else {
313 return gROOT->GetRootFolder()->FindObject(name+1);
314 }
315 }
316 Int_t nch = strlen(name);
317 char csname[128];
318 char *cname = csname;
319 Int_t len = sizeof(csname);
320 if (nch >= len) {
321 len = nch+1;
322 cname = new char[len];
323 }
325 TObject *ret = nullptr;
326 char *slash = strchr(cname,'/');
327 if (slash) {
328 *slash = 0;
329 if (TObject *obj = fFolders->FindObject(cname))
330 ret = obj->FindObject(slash+1);
331 } else {
333 }
334 if (cname != csname)
335 delete [] cname;
336 return ret;
337}
338
339////////////////////////////////////////////////////////////////////////////////
340/// Return a pointer to the first object with name starting at this folder.
341
343{
344 TObject *obj = FindObject(name);
345 if (obj || !fFolders) return obj;
346
347 //if (!obj->InheritsFrom(TFolder::Class())) continue;
348 if (name[0] == '/') return nullptr;
349 TIter next(fFolders);
351 TObject *found;
353 while ((obj=next())) {
354 if (!obj->InheritsFrom(TFolder::Class())) continue;
355 if (obj->IsA() == TClass::Class()) continue;
356 folder = (TFolder*)obj;
357 found = folder->FindObjectAny(name);
358 if (found) return found;
359 }
360 return nullptr;
361}
362
363////////////////////////////////////////////////////////////////////////////////
364/// Folder ownership has been set via
365/// - TFolder::SetOwner
366/// - TCollection::SetOwner on the collection specified to TFolder::AddFolder
367
369{
370 if (!fFolders) return kFALSE;
371 return fFolders->IsOwner();
372}
373
374////////////////////////////////////////////////////////////////////////////////
375/// List folder contents.
376///
377/// If option contains "dump", the Dump function of contained objects is called.
378///
379/// If option contains "print", the Print function of contained objects is called.
380///
381/// By default the ls function of contained objects is called.
382///
383/// Indentation is used to identify the folder tree.
384///
385/// The if option contains a `<regexp>` it be used to match the name of the objects.
386
388{
389 if (!fFolders) return;
391 std::cout <<ClassName()<<"*\t\t"<<GetName()<<"\t"<<GetTitle()<<std::endl;
393
394 TString opt = option;
395 Ssiz_t dump = opt.Index("dump", 0, TString::kIgnoreCase);
396 if (dump != kNPOS)
397 opt.Remove(dump, 4);
398 Ssiz_t print = opt.Index("print", 0, TString::kIgnoreCase);
399 if (print != kNPOS)
400 opt.Remove(print, 5);
401 opt = opt.Strip(TString::kBoth);
402 if (opt == "")
403 opt = "*";
404 TRegexp re(opt, kTRUE);
405
406 TObject *obj;
408 while ((obj = (TObject *) nextobj())) {
409 TString s = obj->GetName();
410 if (s.Index(re) == kNPOS) continue;
411 if (dump != kNPOS)
412 obj->Dump();
413 if (print != kNPOS)
414 obj->Print(option);
415 obj->ls(option);
416 }
418}
419
420////////////////////////////////////////////////////////////////////////////////
421/// Return occurence number of object in the list of objects of this folder.
422/// The function returns the number of objects with the same name as object
423/// found in the list of objects in this folder before object itself.
424/// If only one object is found, return 0.
425
426Int_t TFolder::Occurence(const TObject *object) const
427{
428 Int_t n = 0;
429 if (!fFolders) return 0;
430 TIter next(fFolders);
431 TObject *obj;
432 while ((obj=next())) {
433 if (strcmp(obj->GetName(),object->GetName()) == 0) n++;
434 }
435 if (n <=1) return n-1;
436 n = 0;
437 next.Reset();
438 while ((obj=next())) {
439 if (strcmp(obj->GetName(),object->GetName()) == 0) n++;
440 if (obj == object) return n;
441 }
442 return 0;
443}
444
445////////////////////////////////////////////////////////////////////////////////
446/// Recursively remove object from a folder.
447
452
453////////////////////////////////////////////////////////////////////////////////
454/// Remove object from this folder. obj must be a TObject or a TFolder.
455
457{
458 if (obj == nullptr || fFolders == nullptr) return;
459 fFolders->Remove(obj);
460}
461
462////////////////////////////////////////////////////////////////////////////////
463/// Save all objects in this folder in filename.
464/// Each object in this folder will have a key in the file where the name of
465/// the key will be the name of the object.
466
467void TFolder::SaveAs(const char *filename, Option_t *option) const
468{
469 if (gDirectory) gDirectory->SaveObjectAs(this,filename,option);
470}
471
472////////////////////////////////////////////////////////////////////////////////
473/// Set ownership.
474/// If the folder is declared owner, when the folder is deleted, all
475/// the objects added via TFolder::Add are deleted via TObject::Delete,
476/// otherwise TObject::Clear is called.
477///
478/// NOTE that folder ownership can be set:
479/// - via TFolder::SetOwner
480/// - or via TCollection::SetOwner on the collection specified to TFolder::AddFolder
481
483{
484 if (!fFolders) fFolders = new TList();
485 fFolders->SetOwner(owner);
486}
#define SafeDelete(p)
Definition RConfig.hxx:533
#define b(i)
Definition RSha256.hxx:100
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:131
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
#define BIT(n)
Definition Rtypes.h:91
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
@ 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 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
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:627
#define gROOT
Definition TROOT.h:411
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
static TClass * Class()
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
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:448
void Browse(TBrowser *b) override
Browse this folder.
Definition TFolder.cxx:212
TFolder()
Default constructor used by the Input functions.
Definition TFolder.cxx:111
virtual TObject * FindObjectAny(const char *name) const
Return a pointer to the first object with name starting at this folder.
Definition TFolder.cxx:342
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:181
virtual void Add(TObject *obj)
Add object to this folder. obj must be a TObject or a TFolder.
Definition TFolder.cxx:165
void Clear(Option_t *option="") override
Delete all objects from a folder list.
Definition TFolder.cxx:220
virtual ~TFolder()
Folder destructor.
Definition TFolder.cxx:132
TObject * FindObject(const char *name) const override
Search object identified by name in the tree of folders inside this folder.
Definition TFolder.cxx:305
void ls(Option_t *option="") const override
List folder contents.
Definition TFolder.cxx:387
void SaveAs(const char *filename="", Option_t *option="") const override
Save all objects in this folder in filename.
Definition TFolder.cxx:467
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:230
Bool_t fIsOwner
Definition TFolder.h:34
virtual void SetOwner(Bool_t owner=kTRUE)
Set ownership.
Definition TFolder.cxx:482
Bool_t IsOwner() const
Folder ownership has been set via.
Definition TFolder.cxx:368
virtual Int_t Occurence(const TObject *obj) const
Return occurence number of object in the list of objects of this folder.
Definition TFolder.cxx:426
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:456
void Reset()
A doubly linked list.
Definition TList.h:38
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:457
virtual void Dump() const
Dump contents of object on stdout.
Definition TObject.cxx:366
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:202
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition TObject.cxx:421
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:543
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual TClass * IsA() const
Definition TObject.h:246
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:655
virtual void ls(Option_t *option="") const
The ls function lists the contents of a class on stdout.
Definition TObject.cxx:592
@ kMustCleanup
if object destructor must call RecursiveRemove()
Definition TObject.h:70
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition TROOT.cxx:2890
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition TROOT.cxx:2898
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition TROOT.cxx:2748
Regular expression class.
Definition TRegexp.h:31
Basic string class.
Definition TString.h:138
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition TString.cxx:1170
@ kBoth
Definition TString.h:284
@ kIgnoreCase
Definition TString.h:285
TString & Remove(Ssiz_t pos)
Definition TString.h:693
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:659
const Int_t n
Definition legend1.C:16
TCanvas * slash()
Definition slash.C:1
TLine l
Definition textangle.C:4