Logo ROOT   6.10/09
Reference Guide
TDirectory.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id: 65b4f3646f4e5b2fa77218ba786b7fe4e16e27be $
2 // Author: Rene Brun 28/11/94
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 #include <stdlib.h>
12 
13 #include "Riostream.h"
14 #include "Strlen.h"
15 #include "TDirectory.h"
16 #include "TClassTable.h"
17 #include "TInterpreter.h"
18 #include "THashList.h"
19 #include "TBrowser.h"
20 #include "TROOT.h"
21 #include "TError.h"
22 #include "TClass.h"
23 #include "TRegexp.h"
24 #include "TSystem.h"
25 #include "TVirtualMutex.h"
26 #include "TThreadSlots.h"
27 #include "TMethod.h"
28 
30 
31 const Int_t kMaxLen = 2048;
32 
33 /** \class TDirectory
34 \ingroup Base
35 
36 Describe directory structure in memory.
37 */
38 
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 /// Directory default constructor.
43 
44 TDirectory::TDirectory() : TNamed(), fMother(0),fList(0),fContext(0)
45 {
46 }
47 
48 ////////////////////////////////////////////////////////////////////////////////
49 /// Create a new Directory.
50 ///
51 /// A new directory with name,title is created in the current directory
52 /// The directory header information is immediately saved in the file
53 /// A new key is added in the parent directory
54 ///
55 /// When this constructor is called from a class directly derived
56 /// from TDirectory, the third argument classname MUST be specified.
57 /// In this case, classname must be the name of the derived class.
58 ///
59 /// Note that the directory name cannot contain slashes.
60 
61 TDirectory::TDirectory(const char *name, const char *title, Option_t * /*classname*/, TDirectory* initMotherDir)
62  : TNamed(name, title), fMother(0), fList(0),fContext(0)
63 {
64  if (initMotherDir==0) initMotherDir = gDirectory;
65 
66  if (strchr(name,'/')) {
67  ::Error("TDirectory::TDirectory","directory name (%s) cannot contain a slash", name);
68  gDirectory = 0;
69  return;
70  }
71  if (strlen(GetName()) == 0) {
72  ::Error("TDirectory::TDirectory","directory name cannot be \"\"");
73  gDirectory = 0;
74  return;
75  }
76 
77  Build(initMotherDir ? initMotherDir->GetFile() : 0, initMotherDir);
78 
80 }
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 /// Copy constructor.
84 
85 TDirectory::TDirectory(const TDirectory &directory) : TNamed(directory)
86 {
87  directory.Copy(*this);
88 }
89 
90 ////////////////////////////////////////////////////////////////////////////////
91 /// Destructor.
92 
94 {
95  if (!gROOT) {
96  delete fList;
97  return; //when called by TROOT destructor
98  }
99 
100  if (fList) {
101  fList->Delete("slow");
102  SafeDelete(fList);
103  }
104 
105  CleanTargets();
106 
107  TDirectory* mom = GetMotherDir();
108 
109  if (mom) {
110  mom->Remove(this);
111  }
112 
113  if (gDebug) {
114  Info("~TDirectory", "dtor called for %s", GetName());
115  }
116 }
117 
118 ////////////////////////////////////////////////////////////////////////////////
119 /// Sets the flag controlling the automatic add objects like histograms, TGraph2D, etc
120 /// in memory
121 ///
122 /// By default (fAddDirectory = kTRUE), these objects are automatically added
123 /// to the list of objects in memory.
124 /// Note that in the classes like TH1, TGraph2D supporting this facility,
125 /// one object can be removed from its support directory
126 /// by calling object->SetDirectory(0) or object->SetDirectory(dir) to add it
127 /// to the list of objects in the directory dir.
128 ///
129 /// NOTE that this is a static function. To call it, use:
130 /// ~~~ {.cpp}
131 /// TDirectory::AddDirectory
132 /// ~~~
133 
135 {
136  fgAddDirectory = add;
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// Static function: see TDirectory::AddDirectory for more comments.
141 
143 {
144  return fgAddDirectory;
145 }
146 
147 ////////////////////////////////////////////////////////////////////////////////
148 /// Append object to this directory.
149 ///
150 /// If `replace` is true:
151 /// remove any existing objects with the same name (if the name is not "")
152 
153 void TDirectory::Append(TObject *obj, Bool_t replace /* = kFALSE */)
154 {
155  if (obj == 0 || fList == 0) return;
156 
157  if (replace && obj->GetName() && obj->GetName()[0]) {
158  TObject *old;
159  while (0!=(old = GetList()->FindObject(obj->GetName()))) {
160  Warning("Append","Replacing existing %s: %s (Potential memory leak).",
161  obj->IsA()->GetName(),obj->GetName());
162  ROOT::DirAutoAdd_t func = old->IsA()->GetDirectoryAutoAdd();
163  if (func) {
164  func(old,0);
165  } else {
166  Remove(old);
167  }
168  }
169  }
170 
171  fList->Add(obj);
172  obj->SetBit(kMustCleanup);
173 }
174 
175 ////////////////////////////////////////////////////////////////////////////////
176 /// Browse the content of the directory.
177 
179 {
180  if (b) {
181  TObject *obj = 0;
182  TIter nextin(fList);
183 
184  cd();
185 
186  //Add objects that are only in memory
187  while ((obj = nextin())) {
188  b->Add(obj, obj->GetName());
189  }
190  }
191 }
192 
193 ////////////////////////////////////////////////////////////////////////////////
194 /// Initialise directory to defaults.
195 ///
196 /// If directory is created via default ctor (when dir is read from file)
197 /// don't add it here to the directory since its name is not yet known.
198 /// It will be added to the directory in TKey::ReadObj().
199 
200 void TDirectory::Build(TFile* /*motherFile*/, TDirectory* motherDir)
201 {
202  if (motherDir && strlen(GetName()) != 0) motherDir->Append(this);
203 
204  fList = new THashList(100,50);
205  fMother = motherDir;
207 }
208 
209 ////////////////////////////////////////////////////////////////////////////////
210 /// Clean the pointers to this object (gDirectory, TContext, etc.).
211 
213 {
214  while (fContext) {
215  fContext->fDirectory = 0;
217  }
218 
219  if (gDirectory == this) {
220  TDirectory *cursav = GetMotherDir();
221  if (cursav && cursav != this) {
222  cursav->cd();
223  } else {
224  if (this == gROOT) {
225  gDirectory = 0;
226  } else {
227  gROOT->cd();
228  }
229  }
230  }
231 }
232 
233 ////////////////////////////////////////////////////////////////////////////////
234 /// Fast execution of 'new TBufferFile(TBuffer::kWrite,10000), without having
235 /// a compile time circular dependency ... alternatively we could (should?)
236 /// introduce yet another abstract interface.
237 
239 {
240  typedef void (*tcling_callfunc_Wrapper_t)(void*, int, void**, void*);
241  static tcling_callfunc_Wrapper_t creator = 0;
242  if (creator == 0) {
244  TClass *c = TClass::GetClass("TBufferFile");
245  TMethod *m = c->GetMethodWithPrototype("TBufferFile","TBuffer::EMode,Int_t",kFALSE,ROOT::kExactMatch);
246  creator = (tcling_callfunc_Wrapper_t)( m->InterfaceMethod() );
247  }
249  Int_t size = 10000;
250  void *args[] = { &mode, &size };
251  TBuffer *result;
252  creator(0,2,args,&result);
253  return result;
254 }
255 
256 ////////////////////////////////////////////////////////////////////////////////
257 /// Clone an object.
258 /// This function is called when the directory is not a TDirectoryFile.
259 /// This version has to load the I/O package, hence via Cling.
260 ///
261 /// If autoadd is true and if the object class has a
262 /// DirectoryAutoAdd function, it will be called at the end of the
263 /// function with the parameter gDirector. This usually means that
264 /// the object will be appended to the current ROOT directory.
265 
266 TObject *TDirectory::CloneObject(const TObject *obj, Bool_t autoadd /* = kTRUE */)
267 {
268  // if no default ctor return immediately (error issued by New())
269  char *pobj = (char*)obj->IsA()->New();
270  if (!pobj) {
271  Fatal("CloneObject","Failed to create new object");
272  return 0;
273  }
274 
275  Int_t baseOffset = obj->IsA()->GetBaseClassOffset(TObject::Class());
276  if (baseOffset==-1) {
277  // cl does not inherit from TObject.
278  // Since this is not supported in this function, the only reason we could reach this code
279  // is because something is screwed up in the ROOT code.
280  Fatal("CloneObject","Incorrect detection of the inheritance from TObject for class %s.\n",
281  obj->IsA()->GetName());
282  }
283  TObject *newobj = (TObject*)(pobj+baseOffset);
284 
285  //create a buffer where the object will be streamed
286  //We are forced to go via the I/O package (ie TBufferFile).
287  //Invoking TBufferFile via CINT will automatically load the I/O library
288  TBuffer *buffer = R__CreateBuffer();
289  if (!buffer) {
290  Fatal("CloneObject","Not able to create a TBuffer!");
291  return 0;
292  }
293  buffer->MapObject(obj); //register obj in map to handle self reference
294  const_cast<TObject*>(obj)->Streamer(*buffer);
295 
296  // read new object from buffer
297  buffer->SetReadMode();
298  buffer->ResetMap();
299  buffer->SetBufferOffset(0);
300  buffer->MapObject(newobj); //register obj in map to handle self reference
301  newobj->Streamer(*buffer);
302  newobj->ResetBit(kIsReferenced);
303  newobj->ResetBit(kCanDelete);
304 
305  delete buffer;
306  if (autoadd) {
307  ROOT::DirAutoAdd_t func = obj->IsA()->GetDirectoryAutoAdd();
308  if (func) {
309  func(newobj,this);
310  }
311  }
312  return newobj;
313 }
314 
315 ////////////////////////////////////////////////////////////////////////////////
316 /// Return the current directory for the current thread.
317 
319 {
320  static TDirectory *currentDirectory = 0;
321  if (!gThreadTsd)
322  return currentDirectory;
323  else
324  return *(TDirectory**)(*gThreadTsd)(&currentDirectory,ROOT::kDirectoryThreadSlot);
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Find a directory using apath.
329 /// It apath is null or empty, returns "this" directory.
330 /// Otherwise use apath to find a directory.
331 /// The absolute path syntax is: `file.root:/dir1/dir2`
332 ///
333 /// where file.root is the file and /dir1/dir2 the desired subdirectory
334 /// in the file. Relative syntax is relative to "this" directory. E.g: `../aa`.
335 /// Returns 0 in case path does not exist.
336 /// If printError is true, use Error with 'funcname' to issue an error message.
337 
339  Bool_t printError, const char *funcname)
340 {
341  Int_t nch = 0;
342  if (apath) nch = strlen(apath);
343  if (!nch) {
344  return this;
345  }
346 
347  if (funcname==0 || strlen(funcname)==0) funcname = "GetDirectory";
348 
349  TDirectory *result = this;
350 
351  char *path = new char[nch+1]; path[0] = 0;
352  if (nch) strlcpy(path,apath,nch+1);
353  char *s = (char*)strrchr(path, ':');
354  if (s) {
355  *s = '\0';
357  TDirectory *f = (TDirectory *)gROOT->GetListOfFiles()->FindObject(path);
358  if (!f && !strcmp(gROOT->GetName(), path)) f = gROOT;
359  if (s) *s = ':';
360  if (f) {
361  result = f;
362  if (s && *(s+1)) result = f->GetDirectory(s+1,printError,funcname);
363  delete [] path; return result;
364  } else {
365  if (printError) Error(funcname, "No such file %s", path);
366  delete [] path; return 0;
367  }
368  }
369 
370  // path starts with a slash (assumes current file)
371  if (path[0] == '/') {
372  TDirectory *td = gROOT;
373  result = td->GetDirectory(path+1,printError,funcname);
374  delete [] path; return result;
375  }
376 
377  TObject *obj;
378  char *slash = (char*)strchr(path,'/');
379  if (!slash) { // we are at the lowest level
380  if (!strcmp(path, "..")) {
381  result = GetMotherDir();
382  delete [] path; return result;
383  }
384  obj = Get(path);
385  if (!obj) {
386  if (printError) Error(funcname,"Unknown directory %s", path);
387  delete [] path; return 0;
388  }
389 
390  //Check return object is a directory
391  if (!obj->InheritsFrom(TDirectory::Class())) {
392  if (printError) Error(funcname,"Object %s is not a directory", path);
393  delete [] path; return 0;
394  }
395  delete [] path; return (TDirectory*)obj;
396  }
397 
398  TString subdir(path);
399  slash = (char*)strchr(subdir.Data(),'/');
400  *slash = 0;
401  //Get object with path from current directory/file
402  if (!strcmp(subdir, "..")) {
403  TDirectory* mom = GetMotherDir();
404  if (mom)
405  result = mom->GetDirectory(slash+1,printError,funcname);
406  delete [] path; return result;
407  }
408  obj = Get(subdir);
409  if (!obj) {
410  if (printError) Error(funcname,"Unknown directory %s", subdir.Data());
411  delete [] path; return 0;
412  }
413 
414  //Check return object is a directory
415  if (!obj->InheritsFrom(TDirectory::Class())) {
416  if (printError) Error(funcname,"Object %s is not a directory", subdir.Data());
417  delete [] path; return 0;
418  }
419  result = ((TDirectory*)obj)->GetDirectory(slash+1,printError,funcname);
420  delete [] path; return result;
421 }
422 
423 ////////////////////////////////////////////////////////////////////////////////
424 /// Change current directory to "this" directory.
425 ///
426 /// Using path one can change the current directory to "path". The absolute path
427 /// syntax is: `file.root:/dir1/dir2`
428 /// where `file.root` is the file and `/dir1/dir2` the desired subdirectory
429 /// in the file.
430 ///
431 /// Relative syntax is relative to "this" directory. E.g: `../aa`.
432 ///
433 /// Returns kTRUE in case of success.
434 
435 Bool_t TDirectory::cd(const char *path)
436 {
437  return cd1(path);
438 }
439 
440 ////////////////////////////////////////////////////////////////////////////////
441 /// Change current directory to "this" directory.
442 ///
443 /// Using path one can
444 /// change the current directory to "path". The absolute path syntax is:
445 /// `file.root:/dir1/dir2`
446 /// where `file.root` is the file and `/dir1/dir2` the desired subdirectory
447 /// in the file.
448 ///
449 /// Relative syntax is relative to "this" directory. E.g: `../aa`.
450 ///
451 /// Returns kFALSE in case path does not exist.
452 
453 Bool_t TDirectory::cd1(const char *apath)
454 {
455  Int_t nch = 0;
456  if (apath) nch = strlen(apath);
457  if (!nch) {
458  gDirectory = this;
459  return kTRUE;
460  }
461 
462  TDirectory *where = GetDirectory(apath,kTRUE,"cd");
463  if (where) {
464  where->cd();
465  return kTRUE;
466  }
467  return kFALSE;
468 }
469 
470 ////////////////////////////////////////////////////////////////////////////////
471 /// Change current directory to "path". The absolute path syntax is:
472 /// `file.root:/dir1/dir2`
473 /// where file.root is the file and `/dir1/dir2 the desired subdirectory
474 /// in the file.
475 /// Relative syntax is relative to the current directory `gDirectory`, e.g.: `../aa`.
476 ///
477 /// Returns kTRUE in case of success.
478 
479 Bool_t TDirectory::Cd(const char *path)
480 {
481  return Cd1(path);
482 }
483 
484 ////////////////////////////////////////////////////////////////////////////////
485 /// Change current directory to "path". The path syntax is:
486 /// `file.root:/dir1/dir2`
487 /// where file.root is the file and `/dir1/dir2` the desired subdirectory
488 /// in the file.
489 ///
490 /// Returns kFALSE in case path does not exist.
491 
492 Bool_t TDirectory::Cd1(const char *apath)
493 {
494  // null path is always true (i.e. stay in the current directory)
495  Int_t nch = 0;
496  if (apath) nch = strlen(apath);
497  if (!nch) return kTRUE;
498 
499  TDirectory *where = gDirectory->GetDirectory(apath,kTRUE,"Cd");
500  if (where) {
501  where->cd();
502  return kTRUE;
503  }
504  return kFALSE;
505 }
506 
507 ////////////////////////////////////////////////////////////////////////////////
508 /// Delete all objects from a Directory list.
509 
511 {
512  if (fList) fList->Clear();
513 
514 }
515 
516 ////////////////////////////////////////////////////////////////////////////////
517 /// Delete all objects from memory and directory structure itself.
518 
520 {
521  if (!fList) {
522  return;
523  }
524 
525  // Save the directory key list and header
526  Save();
527 
528  Bool_t fast = kTRUE;
529  TObjLink *lnk = fList->FirstLink();
530  while (lnk) {
531  if (lnk->GetObject()->IsA() == TDirectory::Class()) {fast = kFALSE;break;}
532  lnk = lnk->Next();
533  }
534  // Delete objects from directory list, this in turn, recursively closes all
535  // sub-directories (that were allocated on the heap)
536  // if this dir contains subdirs, we must use the slow option for Delete!
537  // we must avoid "slow" as much as possible, in particular Delete("slow")
538  // with a large number of objects (eg >10^5) would take for ever.
539  if (fast) fList->Delete();
540  else fList->Delete("slow");
541 
542  CleanTargets();
543 }
544 
545 ////////////////////////////////////////////////////////////////////////////////
546 /// Delete all objects from memory.
547 
549 {
550  fList->Delete("slow");
551 }
552 
553 ////////////////////////////////////////////////////////////////////////////////
554 /// Delete Objects or/and keys in a directory.
555 ///
556 /// - namecycle has the format name;cycle
557 /// - namecycle = "" same as namecycle ="T*"
558 /// - name = * means all
559 /// - cycle = * means all cycles (memory and keys)
560 /// - cycle = "" or cycle = 9999 ==> apply to a memory object
561 /// When name=* use T* to delete subdirectories also
562 ///
563 /// To delete one directory, you must specify the directory cycle,
564 /// eg. `file.Delete("dir1;1");`
565 ///
566 /// examples:
567 /// - foo : delete object named foo in memory
568 /// - foo* : delete all objects with a name starting with foo
569 /// - foo;1 : delete cycle 1 of foo on file
570 /// - foo;* : delete all cycles of foo on file and also from memory
571 /// - *;2 : delete all objects on file having the cycle 2
572 /// - *;* : delete all objects from memory and file
573 /// - T*;* : delete all objects from memory and file and all subdirectories
574 
575 void TDirectory::Delete(const char *namecycle)
576 {
577  if (gDebug)
578  Info("Delete","Call for this = %s namecycle = %s",
579  GetName(), (namecycle ? namecycle : "null"));
580 
581  TDirectory::TContext ctxt(this);
582  Short_t cycle;
583  char name[kMaxLen];
584  DecodeNameCycle(namecycle, name, cycle, kMaxLen);
585 
586  Int_t deleteall = 0;
587  Int_t deletetree = 0;
588  if(strcmp(name,"*") == 0) deleteall = 1;
589  if(strcmp(name,"*T") == 0){ deleteall = 1; deletetree = 1;}
590  if(strcmp(name,"T*") == 0){ deleteall = 1; deletetree = 1;}
591  if(namecycle==0 || !namecycle[0]){ deleteall = 1; deletetree = 1;}
592  TRegexp re(name,kTRUE);
593  TString s;
594  Int_t deleteOK = 0;
595 
596 //*-*---------------------Case of Object in memory---------------------
597 // ========================
598  if (cycle >= 9999 ) {
599  TNamed *idcur;
600  TIter next(fList);
601  while ((idcur = (TNamed *) next())) {
602  deleteOK = 0;
603  s = idcur->GetName();
604  if (deleteall || s.Index(re) != kNPOS) {
605  deleteOK = 1;
606  if (idcur->IsA() == TDirectory::Class()) {
607  deleteOK = 2;
608  if (!deletetree && deleteall) deleteOK = 0;
609  }
610  }
611  if (deleteOK != 0) {
612  fList->Remove(idcur);
613  if (deleteOK==2) {
614  // read subdirectories to correctly delete them
615  if (deletetree)
616  ((TDirectory*) idcur)->ReadAll("dirs");
617  idcur->Delete(deletetree ? "T*;*" : "*");
618  delete idcur;
619  } else
620  idcur->Delete(name);
621  }
622  }
623  }
624 }
625 
626 ////////////////////////////////////////////////////////////////////////////////
627 /// Fill Graphics Structure and Paint.
628 ///
629 /// Loop on all objects (memory or file) and all subdirectories
630 
632 {
633  fList->R__FOR_EACH(TObject,Draw)(option);
634 }
635 
636 ////////////////////////////////////////////////////////////////////////////////
637 /// Find object in the list of memory objects.
638 
640 {
641  return fList->FindObject(obj);
642 }
643 
644 ////////////////////////////////////////////////////////////////////////////////
645 /// Find object by name in the list of memory objects.
646 
648 {
649  return fList->FindObject(name);
650 }
651 
652 ////////////////////////////////////////////////////////////////////////////////
653 /// Find object by name in the list of memory objects of the current
654 /// directory or its sub-directories.
655 /// After this call the current directory is not changed.
656 /// To automatically set the current directory where the object is found,
657 /// use FindKeyAny(aname)->ReadObj().
658 
659 TObject *TDirectory::FindObjectAny(const char *aname) const
660 {
661  //object may be already in the list of objects in memory
662  TObject *obj = fList->FindObject(aname);
663  if (obj) return obj;
664 
665  //try with subdirectories
666  TIter next(fList);
667  while( (obj = next()) ) {
668  if (obj->IsA()->InheritsFrom(TDirectory::Class())) {
669  TDirectory* subdir = static_cast<TDirectory*>(obj);
670  TObject *subobj = subdir->TDirectory::FindObjectAny(aname); // Explicitly recurse into _this_ exact function.
671  if (subobj) {
672  return subobj;
673  }
674  }
675  }
676  return 0;
677 }
678 
679 ////////////////////////////////////////////////////////////////////////////////
680 /// Return pointer to object identified by namecycle.
681 ///
682 /// namecycle has the format name;cycle
683 /// - name = * is illegal, cycle = * is illegal
684 /// - cycle = "" or cycle = 9999 ==> apply to a memory object
685 ///
686 /// examples:
687 /// - foo : get object named foo in memory
688 /// if object is not in memory, try with highest cycle from file
689 /// - foo;1 : get cycle 1 of foo on file
690 ///
691 /// The retrieved object should in principle derive from TObject.
692 /// If not, the function TDirectory::GetObject should be called.
693 /// However, this function will still work for a non-TObject, providing that
694 /// the calling application cast the return type to the correct type (which
695 /// is the actual type of the object).
696 ///
697 /// NOTE:
698 ///
699 /// The method GetObject offer better protection and avoid the need
700 /// for any cast:
701 /// ~~~ {.cpp}
702 /// MyClass *obj;
703 /// directory->GetObject("some object",obj);
704 /// if (obj) { ... the object exist and inherits from MyClass ... }
705 /// ~~~
706 ///
707 /// VERY IMPORTANT NOTE:
708 ///
709 /// In case the class of this object derives from TObject but not
710 /// as a first inheritance, one must use dynamic_cast<>().
711 /// #### Example 1: Normal case:
712 /// ~~~ {.cpp}
713 /// class MyClass : public TObject, public AnotherClass
714 /// ~~~
715 /// then on return, one can do:
716 /// ~~~ {.cpp}
717 /// MyClass *obj = (MyClass*)directory->Get("some object of MyClass");
718 /// ~~~
719 /// #### Example 2: Special case:
720 /// ~~~ {.cpp}
721 /// class MyClass : public AnotherClass, public TObject
722 /// ~~~
723 /// then on return, one must do:
724 /// ~~~ {.cpp}
725 /// MyClass *obj = dynamic_cast<MyClass*>(directory->Get("some object of MyClass"));
726 /// ~~~
727 /// Of course, dynamic_cast<> can also be used in the example 1.
728 
729 TObject *TDirectory::Get(const char *namecycle)
730 {
731  Short_t cycle;
732  char name[kMaxLen];
733 
734  DecodeNameCycle(namecycle, name, cycle, kMaxLen);
735  char *namobj = name;
736  Int_t nch = strlen(name);
737  for (Int_t i = nch-1; i > 0; i--) {
738  if (name[i] == '/') {
739  name[i] = 0;
740  TDirectory* dirToSearch=GetDirectory(name);
741  namobj = name + i + 1;
742  name[i] = '/';
743  return dirToSearch?dirToSearch->Get(namobj):0;
744  }
745  }
746 
747 //*-*---------------------Case of Object in memory---------------------
748 // ========================
749  TObject *idcur = fList->FindObject(namobj);
750  if (idcur) {
751  if (idcur==this && strlen(namobj)!=0) {
752  // The object has the same name has the directory and
753  // that's what we picked-up! We just need to ignore
754  // it ...
755  idcur = 0;
756  } else if (cycle == 9999) {
757  return idcur;
758  } else {
759  if (idcur->InheritsFrom(TCollection::Class()))
760  idcur->Delete(); // delete also list elements
761  delete idcur;
762  idcur = 0;
763  }
764  }
765  return idcur;
766 }
767 
768 ////////////////////////////////////////////////////////////////////////////////
769 /// Return pointer to object identified by namecycle.
770 /// The returned object may or may not derive from TObject.
771 ///
772 /// - namecycle has the format name;cycle
773 /// - name = * is illegal, cycle = * is illegal
774 /// - cycle = "" or cycle = 9999 ==> apply to a memory object
775 ///
776 /// VERY IMPORTANT NOTE:
777 ///
778 /// The calling application must cast the returned object to
779 /// the final type, e.g.
780 /// ~~~ {.cpp}
781 /// MyClass *obj = (MyClass*)directory->GetObject("some object of MyClass");
782 /// ~~~
783 
784 void *TDirectory::GetObjectUnchecked(const char *namecycle)
785 {
786  return GetObjectChecked(namecycle,(TClass*)0);
787 }
788 
789 ////////////////////////////////////////////////////////////////////////////////
790 /// See documentation of TDirectory::GetObjectCheck(const char *namecycle, const TClass *cl)
791 
792 void *TDirectory::GetObjectChecked(const char *namecycle, const char* classname)
793 {
794  return GetObjectChecked(namecycle,TClass::GetClass(classname));
795 }
796 
797 
798 ////////////////////////////////////////////////////////////////////////////////
799 /// Return pointer to object identified by namecycle if and only if the actual
800 /// object is a type suitable to be stored as a pointer to a "expectedClass"
801 /// If expectedClass is null, no check is performed.
802 ///
803 /// namecycle has the format `name;cycle`
804 /// - name = * is illegal, cycle = * is illegal
805 /// - cycle = "" or cycle = 9999 ==> apply to a memory object
806 ///
807 /// VERY IMPORTANT NOTE:
808 ///
809 /// The calling application must cast the returned pointer to
810 /// the type described by the 2 arguments (i.e. cl):
811 /// ~~~ {.cpp}
812 /// MyClass *obj = (MyClass*)directory->GetObjectChecked("some object of MyClass","MyClass"));
813 /// ~~~
814 /// Note: We recommend using the method TDirectory::GetObject:
815 /// ~~~ {.cpp}
816 /// MyClass *obj = 0;
817 /// directory->GetObject("some object inheriting from MyClass",obj);
818 /// if (obj) { ... we found what we are looking for ... }
819 /// ~~~
820 
821 void *TDirectory::GetObjectChecked(const char *namecycle, const TClass* expectedClass)
822 {
823  Short_t cycle;
824  char name[kMaxLen];
825 
826  DecodeNameCycle(namecycle, name, cycle, kMaxLen);
827  char *namobj = name;
828  Int_t nch = strlen(name);
829  for (Int_t i = nch-1; i > 0; i--) {
830  if (name[i] == '/') {
831  name[i] = 0;
832  TDirectory* dirToSearch=GetDirectory(name);
833  namobj = name + i + 1;
834  name[i] = '/';
835  if (dirToSearch) {
836  return dirToSearch->GetObjectChecked(namobj, expectedClass);
837  } else {
838  return 0;
839  }
840  }
841  }
842 
843 //*-*---------------------Case of Object in memory---------------------
844 // ========================
845  if (expectedClass==0 || expectedClass->IsTObject()) {
846  TObject *objcur = fList->FindObject(namobj);
847  if (objcur) {
848  if (objcur==this && strlen(namobj)!=0) {
849  // The object has the same name has the directory and
850  // that's what we picked-up! We just need to ignore
851  // it ...
852  objcur = 0;
853  } else if (cycle == 9999) {
854  // Check type
855  if (expectedClass && objcur->IsA()->GetBaseClassOffset(expectedClass) == -1) return 0;
856  else return objcur;
857  } else {
858  if (objcur->InheritsFrom(TCollection::Class()))
859  objcur->Delete(); // delete also list elements
860  delete objcur;
861  objcur = 0;
862  }
863  }
864  }
865 
866  return 0;
867 }
868 
869 ////////////////////////////////////////////////////////////////////////////////
870 /// Returns the full path of the directory. E.g. `file:/dir1/dir2`.
871 /// The returned path will be re-used by the next call to GetPath().
872 
873 const char *TDirectory::GetPathStatic() const
874 {
875  static char *path = 0;
876  const int kMAXDEPTH = 128;
877  const TDirectory *d[kMAXDEPTH];
878  const TDirectory *cur = this;
879  int depth = 0, len = 0;
880 
881  d[depth++] = cur;
882  len = strlen(cur->GetName()) + 1; // +1 for the /
883 
884  while (cur->fMother && depth < kMAXDEPTH) {
885  cur = (TDirectory *)cur->fMother;
886  d[depth++] = cur;
887  len += strlen(cur->GetName()) + 1;
888  }
889 
890  if (path) delete [] path;
891  path = new char[len+2];
892 
893  for (int i = depth-1; i >= 0; i--) {
894  if (i == depth-1) { // file or TROOT name
895  strlcpy(path, d[i]->GetName(),len+2);
896  strlcat(path, ":",len+2);
897  if (i == 0) strlcat(path, "/",len+2);
898  } else {
899  strlcat(path, "/",len+2);
900  strlcat(path, d[i]->GetName(),len+2);
901  }
902  }
903 
904  return path;
905 }
906 
907 ////////////////////////////////////////////////////////////////////////////////
908 /// Returns the full path of the directory. E.g. `file:/dir1/dir2`.
909 /// The returned path will be re-used by the next call to GetPath().
910 
911 const char *TDirectory::GetPath() const
912 {
913  //
914  TString* buf = &(const_cast<TDirectory*>(this)->fPathBuffer);
915 
916  FillFullPath(*buf);
917  if (GetMotherDir()==0) // case of file
918  buf->Append("/");
919 
920  return buf->Data();
921 }
922 
923 ////////////////////////////////////////////////////////////////////////////////
924 /// Recursive method to fill full path for directory.
925 
927 {
928  TDirectory* mom = GetMotherDir();
929  if (mom!=0) {
930  mom->FillFullPath(buf);
931  buf += "/";
932  buf += GetName();
933  } else {
934  buf = GetName();
935  buf +=":";
936  }
937 }
938 
939 ////////////////////////////////////////////////////////////////////////////////
940 /// Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
941 ///
942 /// Returns 0 in case of error or if a sub-directory (hierarchy) with the requested
943 /// name already exists.
944 /// Returns a pointer to the created sub-directory or to the top sub-directory of
945 /// the hierarchy (in the above example, the returned TDirectory * always points
946 /// to "a").
947 /// In particular, the steps to create first a/b/c and then a/b/d without receiving
948 /// errors are:
949 /// ~~~ {.cpp}
950 /// TFile * file = new TFile("afile","RECREATE");
951 /// file->mkdir("a");
952 /// file->cd("a");
953 /// gDirectory->mkdir("b/c");
954 /// gDirectory->cd("b");
955 /// gDirectory->mkdir("d");
956 /// ~~~
957 
958 TDirectory *TDirectory::mkdir(const char *name, const char *title)
959 {
960  if (!name || !title || !name[0]) return 0;
961  if (!title[0]) title = name;
962  TDirectory *newdir = 0;
963  if (const char *slash = strchr(name,'/')) {
964  Long_t size = Long_t(slash-name);
965  char *workname = new char[size+1];
966  strncpy(workname, name, size);
967  workname[size] = 0;
968  TDirectory *tmpdir;
969  GetObject(workname,tmpdir);
970  if (!tmpdir) {
971  tmpdir = mkdir(workname,title);
972  if (!tmpdir) return 0;
973  }
974  delete[] workname;
975  if (!tmpdir) return 0;
976  if (!newdir) newdir = tmpdir;
977  tmpdir->mkdir(slash+1);
978  return newdir;
979  }
980 
981  TDirectory::TContext ctxt(this);
982 
983  newdir = new TDirectory(name, title, "", this);
984 
985  return newdir;
986 }
987 
988 ////////////////////////////////////////////////////////////////////////////////
989 /// List Directory contents.
990 ///
991 /// Indentation is used to identify the directory tree
992 /// Subdirectories are listed first, then objects in memory.
993 ///
994 /// The option can has the following format:
995 ///
996 /// [<regexp>]
997 ///
998 /// The `<regexp>` will be used to match the name of the objects.
999 /// By default memory and disk objects are listed.
1000 
1001 void TDirectory::ls(Option_t *option) const
1002 {
1005 
1006  TString opta = option;
1007  TString opt = opta.Strip(TString::kBoth);
1008  Bool_t memobj = kTRUE;
1009  TString reg = "*";
1010  if (opt.BeginsWith("-m")) {
1011  if (opt.Length() > 2)
1012  reg = opt(2,opt.Length());
1013  } else if (opt.BeginsWith("-d")) {
1014  memobj = kFALSE;
1015  if (opt.Length() > 2)
1016  reg = opt(2,opt.Length());
1017  } else if (!opt.IsNull())
1018  reg = opt;
1019 
1020  TRegexp re(reg, kTRUE);
1021 
1022  if (memobj) {
1023  TObject *obj;
1024  TIter nextobj(fList);
1025  while ((obj = (TObject *) nextobj())) {
1026  TString s = obj->GetName();
1027  if (s.Index(re) == kNPOS) continue;
1028  obj->ls(option); //*-* Loop on all the objects in memory
1029  }
1030  }
1032 }
1033 
1034 ////////////////////////////////////////////////////////////////////////////////
1035 /// Paint all objects in the directory.
1036 
1038 {
1039  fList->R__FOR_EACH(TObject,Paint)(option);
1040 }
1041 
1042 ////////////////////////////////////////////////////////////////////////////////
1043 /// Print all objects in the directory.
1044 
1045 void TDirectory::Print(Option_t *option) const
1046 {
1047  fList->R__FOR_EACH(TObject,Print)(option);
1048 }
1049 
1050 ////////////////////////////////////////////////////////////////////////////////
1051 /// Print the path of the directory.
1052 
1053 void TDirectory::pwd() const
1054 {
1055  Printf("%s", GetPath());
1056 }
1057 
1058 ////////////////////////////////////////////////////////////////////////////////
1059 /// Recursively remove object from a Directory.
1060 
1062 {
1063  fList->RecursiveRemove(obj);
1064 }
1065 
1066 ////////////////////////////////////////////////////////////////////////////////
1067 /// Remove an object from the in-memory list.
1068 
1070 {
1071  TObject *p = 0;
1072  if (fList) {
1073  p = fList->Remove(obj);
1074  }
1075  return p;
1076 }
1077 
1078 ////////////////////////////////////////////////////////////////////////////////
1079 /// Removes subdirectory from the directory
1080 /// When directory is deleted, all keys in all subdirectories will be
1081 /// read first and deleted from file (if exists)
1082 /// Equivalent call is Delete("name;*");
1083 
1084 void TDirectory::rmdir(const char *name)
1085 {
1086  if ((name==0) || (*name==0)) return;
1087 
1088  TString mask(name);
1089  mask+=";*";
1090  Delete(mask);
1091 }
1092 
1093 ////////////////////////////////////////////////////////////////////////////////
1094 /// Save object in filename,
1095 /// if filename is 0 or "", a file with "objectname.root" is created.
1096 /// The name of the key is the object name.
1097 /// If the operation is successful, it returns the number of bytes written to the file
1098 /// otherwise it returns 0.
1099 /// By default a message is printed. Use option "q" to not print the message.
1100 /// If filename contains ".json" extension, JSON representation of the object
1101 /// will be created and saved in the text file. Such file can be used in
1102 /// JavaScript ROOT (https://root.cern.ch/js/) to display object in web browser
1103 /// When creating JSON file, option string may contain compression level from 0 to 3 (default 0)
1104 
1105 Int_t TDirectory::SaveObjectAs(const TObject *obj, const char *filename, Option_t *option) const
1106 {
1107  if (!obj) return 0;
1108  Int_t nbytes = 0;
1109  TString fname = filename;
1110  if (!filename || !filename[0]) {
1111  fname.Form("%s.root",obj->GetName());
1112  }
1113  TString cmd;
1114  if (fname.Index(".json") > 0) {
1115  cmd.Form("TBufferJSON::ExportToFile(\"%s\",(TObject*) %s, \"%s\");", fname.Data(), TString::LLtoa((Long_t)obj, 10).Data(), (option ? option : ""));
1116  nbytes = gROOT->ProcessLine(cmd);
1117  } else {
1118  cmd.Form("TFile::Open(\"%s\",\"recreate\");",fname.Data());
1119  TContext ctxt; // The TFile::Open will change the current directory.
1120  TDirectory *local = (TDirectory*)gROOT->ProcessLine(cmd);
1121  if (!local) return 0;
1122  nbytes = obj->Write();
1123  delete local;
1124  }
1125  TString opt(option);
1126  opt.ToLower();
1127  if (!opt.Contains("q")) {
1128  if (!gSystem->AccessPathName(fname.Data())) obj->Info("SaveAs", "ROOT file %s has been created", fname.Data());
1129  }
1130  return nbytes;
1131 }
1132 
1133 ////////////////////////////////////////////////////////////////////////////////
1134 /// Set the name for directory
1135 /// If the directory name is changed after the directory was written once,
1136 /// ROOT currently would NOT change the name of correspondent key in the
1137 /// mother directory.
1138 /// DO NOT use this method to 'rename a directory'.
1139 /// Renaming a directory is currently NOT supported.
1140 
1141 void TDirectory::SetName(const char* newname)
1142 {
1143  TNamed::SetName(newname);
1144 }
1145 
1146 ////////////////////////////////////////////////////////////////////////////////
1147 /// Encode the name and cycle into buffer like: "aap;2".
1148 
1149 void TDirectory::EncodeNameCycle(char *buffer, const char *name, Short_t cycle)
1150 {
1151  if (cycle == 9999)
1152  strcpy(buffer, name);
1153  else
1154  sprintf(buffer, "%s;%d", name, cycle);
1155 }
1156 
1157 ////////////////////////////////////////////////////////////////////////////////
1158 /// Decode a namecycle "aap;2" into name "aap" and cycle "2". Destination
1159 /// buffer size for name (including string terminator) should be specified in
1160 /// namesize.
1161 
1162 void TDirectory::DecodeNameCycle(const char *buffer, char *name, Short_t &cycle,
1163  const size_t namesize)
1164 {
1165  size_t len = 0;
1166  const char *ni = strchr(buffer, ';');
1167 
1168  if (ni) {
1169  // Found ';'
1170  len = ni - buffer;
1171  ++ni;
1172  } else {
1173  // No ';' found
1174  len = strlen(buffer);
1175  ni = &buffer[len];
1176  }
1177 
1178  if (namesize) {
1179  if (len > namesize-1ul) len = namesize-1; // accommodate string terminator
1180  } else {
1181  ::Warning("TDirectory::DecodeNameCycle",
1182  "Using unsafe version: invoke this metod by specifying the buffer size");
1183  }
1184 
1185  strncpy(name, buffer, len);
1186  name[len] = '\0';
1187 
1188  if (*ni == '*')
1189  cycle = 10000;
1190  else if (isdigit(*ni)) {
1191  long parsed = strtol(ni,nullptr,10);
1192  if (parsed >= (long) std::numeric_limits<Short_t>::max())
1193  cycle = 0;
1194  else
1195  cycle = (Short_t)parsed;
1196  } else
1197  cycle = 9999;
1198 }
1199 
1200 ////////////////////////////////////////////////////////////////////////////////
1201 /// Register a TContext pointing to this TDirectory object
1202 
1205  if (fContext) {
1206  TContext *current = fContext;
1207  while(current->fNext) {
1208  current = current->fNext;
1209  }
1210  current->fNext = ctxt;
1211  ctxt->fPrevious = current;
1212  } else {
1213  fContext = ctxt;
1214  }
1215 }
1216 
1217 ////////////////////////////////////////////////////////////////////////////////
1218 /// See TDirectoryFile::WriteTObject for details
1219 
1220 Int_t TDirectory::WriteTObject(const TObject *obj, const char *name, Option_t * /*option*/, Int_t /*bufsize*/)
1221 {
1222  const char *objname = "no name specified";
1223  if (name) objname = name;
1224  else if (obj) objname = obj->GetName();
1225  Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.",GetName(),objname);
1226  return 0;
1227 }
1228 
1229 ////////////////////////////////////////////////////////////////////////////////
1230 /// UnRegister a TContext pointing to this TDirectory object
1231 
1234  if (ctxt==fContext) {
1235  fContext = ctxt->fNext;
1236  if (fContext) fContext->fPrevious = 0;
1237  ctxt->fPrevious = ctxt->fNext = 0;
1238  } else {
1239  TContext *next = ctxt->fNext;
1240  ctxt->fPrevious->fNext = next;
1241  if (next) next->fPrevious = ctxt->fPrevious;
1242  ctxt->fPrevious = ctxt->fNext = 0;
1243  }
1244 }
1245 
1246 ////////////////////////////////////////////////////////////////////////////////
1247 /// Set the current directory to null.
1248 /// This is called from the TContext destructor. Since the destructor is
1249 /// inline, we do not want to have it directly use a global variable.
1250 
1252 {
1253  gDirectory = 0;
1254 }
void Add(TObject *obj, const char *name=0, Int_t check=-1)
Add object with name to browser.
Definition: TBrowser.cxx:261
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition: TObject.cxx:778
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1272
void SetBufferOffset(Int_t offset=0)
Definition: TBuffer.h:88
virtual void Draw(Option_t *option="")
Fill Graphics Structure and Paint.
Definition: TDirectory.cxx:631
virtual void Copy(TObject &) const
Copy this to obj.
Definition: TDirectory.h:124
virtual ~TDirectory()
Destructor.
Definition: TDirectory.cxx:93
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition: TROOT.cxx:2569
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:409
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:847
virtual void Build(TFile *motherFile=0, TDirectory *motherDir=0)
Initialise directory to defaults.
Definition: TDirectory.cxx:200
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
Definition: TDirectory.cxx:729
const char Option_t
Definition: RtypesCore.h:62
virtual TDirectory * GetMotherDir() const
Definition: TDirectory.h:150
void GetObject(const char *namecycle, T *&ptr)
Definition: TDirectory.h:137
virtual void Print(Option_t *option="") const
Print all objects in the directory.
TList * fList
Definition: TDirectory.h:89
virtual TObject * CloneObject(const TObject *obj, Bool_t autoadd=kTRUE)
Clone an object.
Definition: TDirectory.cxx:266
const Ssiz_t kNPOS
Definition: RtypesCore.h:115
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
virtual const char * GetPathStatic() const
Returns the full path of the directory.
Definition: TDirectory.cxx:873
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:46
virtual TObject * FindObject(const char *name) const
Find object by name in the list of memory objects.
Definition: TDirectory.cxx:647
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
Regular expression class.
Definition: TRegexp.h:31
void FillFullPath(TString &buf) const
Recursive method to fill full path for directory.
Definition: TDirectory.cxx:926
#define gROOT
Definition: TROOT.h:375
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:587
virtual Int_t WriteTObject(const TObject *obj, const char *name=0, Option_t *="", Int_t=0)
See TDirectoryFile::WriteTObject for details.
Basic string class.
Definition: TString.h:129
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1099
int Int_t
Definition: RtypesCore.h:41
virtual TDirectory * mkdir(const char *name, const char *title="")
Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
Definition: TDirectory.cxx:958
bool Bool_t
Definition: RtypesCore.h:59
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:57
TContext * fPrevious
Pointer to the previous current directory.
Definition: TDirectory.h:44
virtual Int_t SaveObjectAs(const TObject *, const char *="", Option_t *="") const
Save object in filename, if filename is 0 or "", a file with "objectname.root" is created...
R__EXTERN void **(* gThreadTsd)(void *, Int_t)
Definition: TThreadSlots.h:40
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:687
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:501
virtual void * GetObjectChecked(const char *namecycle, const char *classname)
See documentation of TDirectory::GetObjectCheck(const char *namecycle, const TClass *cl) ...
Definition: TDirectory.cxx:792
if object in a list can be deleted
Definition: TObject.h:58
TString fPathBuffer
Definition: TDirectory.h:91
#define SafeDelete(p)
Definition: RConfig.h:499
void Class()
Definition: Class.C:29
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Definition: THashList.h:34
void * InterfaceMethod() const
Return pointer to the interface method.
Definition: TFunction.cxx:208
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void Save()
Definition: TDirectory.h:177
virtual void Paint(Option_t *option="")
Paint all objects in the directory.
Bool_t cd1(const char *path)
flag to add histograms, graphs,etc to the directory
Definition: TDirectory.cxx:453
TString & Append(const char *cs)
Definition: TString.h:497
virtual void Close(Option_t *option="")
Delete all objects from memory and directory structure itself.
Definition: TDirectory.cxx:519
virtual void rmdir(const char *name)
Removes subdirectory from the directory When directory is deleted, all keys in all subdirectories wil...
virtual TList * GetList() const
Definition: TDirectory.h:147
virtual TFile * GetFile() const
Definition: TDirectory.h:145
virtual void ls(Option_t *option="") const
The ls function lists the contents of a class on stdout.
Definition: TObject.cxx:485
virtual void pwd() const
Print the path of the directory.
const Int_t kMaxLen
Definition: TDirectory.cxx:31
virtual void Delete(const char *namecycle="")
Delete Objects or/and keys in a directory.
Definition: TDirectory.cxx:575
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add objects like histograms, TGraph2D, etc in memory...
Definition: TDirectory.cxx:134
virtual void Delete(Option_t *option="")
Delete this object.
Definition: TObject.cxx:176
Using a TBrowser one can browse all ROOT objects.
Definition: TBrowser.h:37
TContext * fNext
Pointer to the next TContext in the implied list of context pointing to fPrevious.
Definition: TDirectory.h:45
virtual void Browse(TBrowser *b)
Browse the content of the directory.
Definition: TDirectory.cxx:178
R__EXTERN TSystem * gSystem
Definition: TSystem.h:539
TContext * fContext
Buffer for GetPath() function.
Definition: TDirectory.h:92
virtual TObject * Remove(TObject *obj)
Remove object from the list.
Definition: TList.cxx:679
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:436
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:563
TDirectory * fDirectory
Definition: TDirectory.h:43
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2332
TMarker * m
Definition: textangle.C:8
virtual void * GetObjectUnchecked(const char *namecycle)
Return pointer to object identified by namecycle.
Definition: TDirectory.cxx:784
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
static Bool_t Cd1(const char *path)
Change current directory to "path".
Definition: TDirectory.cxx:492
Ssiz_t Length() const
Definition: TString.h:388
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
Definition: TDirectory.cxx:153
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1080
void SetReadMode()
Set buffer in read mode.
Definition: TBuffer.cxx:271
short Short_t
Definition: RtypesCore.h:35
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition: TROOT.cxx:2632
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:71
virtual const char * GetPath() const
Returns the full path of the directory.
Definition: TDirectory.cxx:911
if object destructor must call RecursiveRemove()
Definition: TObject.h:59
virtual TObjLink * FirstLink() const
Definition: TList.h:97
#define Printf
Definition: TGeoToOCC.h:18
virtual void Clear(Option_t *option="")
Delete all objects from a Directory list.
Definition: TDirectory.cxx:510
TObject * fMother
Definition: TDirectory.h:88
#define R__LOCKGUARD2(mutex)
const Bool_t kFALSE
Definition: RtypesCore.h:92
long Long_t
Definition: RtypesCore.h:50
virtual void MapObject(const TObject *obj, UInt_t offset=1)=0
virtual void SetName(const char *newname)
Set the name for directory If the directory name is changed after the directory was written once...
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
static Bool_t Cd(const char *path)
Change current directory to "path".
Definition: TDirectory.cxx:479
#define ClassImp(name)
Definition: Rtypes.h:336
double f(double x)
static void EncodeNameCycle(char *buffer, const char *name, Short_t cycle)
Encode the name and cycle into buffer like: "aap;2".
Describe directory structure in memory.
Definition: TDirectory.h:34
static TDirectory *& CurrentDirectory()
Return the current directory for the current thread.
Definition: TDirectory.cxx:318
static Bool_t AddDirectoryStatus()
Static function: see TDirectory::AddDirectory for more comments.
Definition: TDirectory.cxx:142
double func(double *x, double *p)
Definition: stressTF1.cxx:213
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:572
static void DecodeNameCycle(const char *namecycle, char *name, Short_t &cycle, const size_t namesize=0)
Decode a namecycle "aap;2" into name "aap" and cycle "2".
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2885
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:353
TCanvas * slash()
Definition: slash.C:1
Bool_t IsNull() const
Definition: TString.h:385
Mother of all ROOT objects.
Definition: TObject.h:37
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition: TROOT.cxx:2624
typedef void((*Func_t)())
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5575
static TBuffer * R__CreateBuffer()
Fast execution of &#39;new TBufferFile(TBuffer::kWrite,10000), without having a compile time circular dep...
Definition: TDirectory.cxx:238
virtual Bool_t cd(const char *path=0)
Change current directory to "this" directory.
Definition: TDirectory.cxx:435
virtual void Add(TObject *obj)
Definition: TList.h:77
void(* DirAutoAdd_t)(void *, TDirectory *)
Definition: Rtypes.h:107
virtual void RecursiveRemove(TObject *obj)
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition: TList.cxx:639
virtual void DeleteAll(Option_t *option="")
Delete all objects from memory.
Definition: TDirectory.cxx:548
virtual void ls(Option_t *option="") const
List Directory contents.
Each ROOT class (see TClass) has a linked list of methods.
Definition: TMethod.h:38
virtual TDirectory * GetDirectory(const char *namecycle, Bool_t printError=false, const char *funcname="GetDirectory")
Find a directory using apath.
Definition: TDirectory.cxx:338
TDirectory()
Directory default constructor.
Definition: TDirectory.cxx:44
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
if object is referenced by a TRef or TRefArray
Definition: TObject.h:61
R__EXTERN Int_t gDebug
Definition: Rtypes.h:83
static TString LLtoa(Long64_t value, Int_t base)
Converts a Long64_t to a TString with respect to the base specified (2-36).
Definition: TString.cxx:2131
virtual void ResetMap()=0
#define gDirectory
Definition: TDirectory.h:211
double result[121]
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:901
void RegisterContext(TContext *ctxt)
Register a TContext pointing to this TDirectory object.
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:364
TMethod * GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition: TClass.cxx:4217
virtual void RecursiveRemove(TObject *obj)
Recursively remove object from a Directory.
const Bool_t kTRUE
Definition: RtypesCore.h:91
virtual void CleanTargets()
Clean the pointers to this object (gDirectory, TContext, etc.).
Definition: TDirectory.cxx:212
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:859
void UnregisterContext(TContext *ctxt)
UnRegister a TContext pointing to this TDirectory object.
static Bool_t fgAddDirectory
Pointer to a list of TContext object pointing to this TDirectory.
Definition: TDirectory.h:93
void CdNull()
Set the current directory to null.
const char * Data() const
Definition: TString.h:347
virtual TObject * FindObjectAny(const char *name) const
Find object by name in the list of memory objects of the current directory or its sub-directories...
Definition: TDirectory.cxx:659