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