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 &&context : extraWait) {
276  // Wait until the TContext is done spinning
277  // over the lock.
278  while(context->fActiveDestructor);
279  context->fDirectoryWait = false;
280  }
281 
282  if (gDirectory == this) {
283  TDirectory *cursav = GetMotherDir();
284  if (cursav && cursav != this) {
285  cursav->cd();
286  } else {
287  if (this == gROOT) {
288  gDirectory = nullptr;
289  } else {
290  gROOT->cd();
291  }
292  }
293  }
294 }
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 /// Fast execution of 'new TBufferFile(TBuffer::kWrite,10000), without having
298 /// a compile time circular dependency ... alternatively we could (should?)
299 /// introduce yet another abstract interface.
300 
302 {
303  typedef void (*tcling_callfunc_Wrapper_t)(void*, int, void**, void*);
304  static tcling_callfunc_Wrapper_t creator = nullptr;
305  if (!creator) {
307  TClass *c = TClass::GetClass("TBufferFile");
308  TMethod *m = c->GetMethodWithPrototype("TBufferFile","TBuffer::EMode,Int_t",kFALSE,ROOT::kExactMatch);
309  creator = (tcling_callfunc_Wrapper_t)( m->InterfaceMethod() );
310  }
312  Int_t size = 10000;
313  void *args[] = { &mode, &size };
314  TBuffer *result;
315  creator(0,2,args,&result);
316  return result;
317 }
318 
319 ////////////////////////////////////////////////////////////////////////////////
320 /// Clone an object.
321 /// This function is called when the directory is not a TDirectoryFile.
322 /// This version has to load the I/O package, hence via Cling.
323 ///
324 /// If autoadd is true and if the object class has a
325 /// DirectoryAutoAdd function, it will be called at the end of the
326 /// function with the parameter gDirector. This usually means that
327 /// the object will be appended to the current ROOT directory.
328 
329 TObject *TDirectory::CloneObject(const TObject *obj, Bool_t autoadd /* = kTRUE */)
330 {
331  // if no default ctor return immediately (error issued by New())
332  char *pobj = (char*)obj->IsA()->New();
333  if (!pobj) {
334  Fatal("CloneObject","Failed to create new object");
335  return nullptr;
336  }
337 
338  Int_t baseOffset = obj->IsA()->GetBaseClassOffset(TObject::Class());
339  if (baseOffset==-1) {
340  // cl does not inherit from TObject.
341  // Since this is not supported in this function, the only reason we could reach this code
342  // is because something is screwed up in the ROOT code.
343  Fatal("CloneObject","Incorrect detection of the inheritance from TObject for class %s.\n",
344  obj->IsA()->GetName());
345  }
346  TObject *newobj = (TObject*)(pobj+baseOffset);
347 
348  //create a buffer where the object will be streamed
349  //We are forced to go via the I/O package (ie TBufferFile).
350  //Invoking TBufferFile via CINT will automatically load the I/O library
351  TBuffer *buffer = R__CreateBuffer();
352  if (!buffer) {
353  Fatal("CloneObject","Not able to create a TBuffer!");
354  return nullptr;
355  }
356  buffer->MapObject(obj); //register obj in map to handle self reference
357  const_cast<TObject*>(obj)->Streamer(*buffer);
358 
359  // read new object from buffer
360  buffer->SetReadMode();
361  buffer->ResetMap();
362  buffer->SetBufferOffset(0);
363  buffer->MapObject(newobj); //register obj in map to handle self reference
364  newobj->Streamer(*buffer);
365  newobj->ResetBit(kIsReferenced);
366  newobj->ResetBit(kCanDelete);
367 
368  delete buffer;
369  if (autoadd) {
370  ROOT::DirAutoAdd_t func = obj->IsA()->GetDirectoryAutoAdd();
371  if (func) {
372  func(newobj,this);
373  }
374  }
375  return newobj;
376 }
377 
378 ////////////////////////////////////////////////////////////////////////////////
379 /// Return the current directory for the current thread.
380 
382 {
383  static TDirectory *currentDirectory = nullptr;
384  if (!gThreadTsd)
385  return currentDirectory;
386  else
387  return *(TDirectory**)(*gThreadTsd)(&currentDirectory,ROOT::kDirectoryThreadSlot);
388 }
389 
390 ////////////////////////////////////////////////////////////////////////////////
391 /// Find a directory using apath.
392 /// It apath is null or empty, returns "this" directory.
393 /// Otherwise use apath to find a directory.
394 /// The absolute path syntax is: `file.root:/dir1/dir2`
395 ///
396 /// where file.root is the file and /dir1/dir2 the desired subdirectory
397 /// in the file. Relative syntax is relative to "this" directory. E.g: `../aa`.
398 /// Returns 0 in case path does not exist.
399 /// If printError is true, use Error with 'funcname' to issue an error message.
400 
402  Bool_t printError, const char *funcname)
403 {
404  Int_t nch = 0;
405  if (apath) nch = strlen(apath);
406  if (!nch) {
407  return this;
408  }
409 
410  if (funcname==0 || strlen(funcname)==0) funcname = "GetDirectory";
411 
412  TDirectory *result = this;
413 
414  char *path = new char[nch+1]; path[0] = 0;
415  if (nch) strlcpy(path,apath,nch+1);
416  char *s = (char*)strrchr(path, ':');
417  if (s) {
418  *s = '\0';
420  TDirectory *f = (TDirectory *)gROOT->GetListOfFiles()->FindObject(path);
421  if (!f && !strcmp(gROOT->GetName(), path)) f = gROOT;
422  if (s) *s = ':';
423  if (f) {
424  result = f;
425  if (s && *(s+1)) result = f->GetDirectory(s+1,printError,funcname);
426  delete [] path; return result;
427  } else {
428  if (printError) Error(funcname, "No such file %s", path);
429  delete [] path; return nullptr;
430  }
431  }
432 
433  // path starts with a slash (assumes current file)
434  if (path[0] == '/') {
435  TDirectory *td = gROOT;
436  result = td->GetDirectory(path+1,printError,funcname);
437  delete [] path; return result;
438  }
439 
440  TObject *obj;
441  char *slash = (char*)strchr(path,'/');
442  if (!slash) { // we are at the lowest level
443  if (!strcmp(path, "..")) {
444  result = GetMotherDir();
445  delete [] path; return result;
446  }
447  obj = Get(path);
448  if (!obj) {
449  if (printError) Error(funcname,"Unknown directory %s", path);
450  delete [] path; return nullptr;
451  }
452 
453  //Check return object is a directory
454  if (!obj->InheritsFrom(TDirectory::Class())) {
455  if (printError) Error(funcname,"Object %s is not a directory", path);
456  delete [] path; return nullptr;
457  }
458  delete [] path; return (TDirectory*)obj;
459  }
460 
461  TString subdir(path);
462  slash = (char*)strchr(subdir.Data(),'/');
463  *slash = 0;
464  //Get object with path from current directory/file
465  if (!strcmp(subdir, "..")) {
466  TDirectory* mom = GetMotherDir();
467  if (mom)
468  result = mom->GetDirectory(slash+1,printError,funcname);
469  delete [] path; return result;
470  }
471  obj = Get(subdir);
472  if (!obj) {
473  if (printError) Error(funcname,"Unknown directory %s", subdir.Data());
474  delete [] path; return nullptr;
475  }
476 
477  //Check return object is a directory
478  if (!obj->InheritsFrom(TDirectory::Class())) {
479  if (printError) Error(funcname,"Object %s is not a directory", subdir.Data());
480  delete [] path; return nullptr;
481  }
482  result = ((TDirectory*)obj)->GetDirectory(slash+1,printError,funcname);
483  delete [] path; return result;
484 }
485 
486 ////////////////////////////////////////////////////////////////////////////////
487 /// Change current directory to "this" directory.
488 ///
489 /// Using path one can change the current directory to "path". The absolute path
490 /// syntax is: `file.root:/dir1/dir2`
491 /// where `file.root` is the file and `/dir1/dir2` the desired subdirectory
492 /// in the file.
493 ///
494 /// Relative syntax is relative to "this" directory. E.g: `../aa`.
495 ///
496 /// Returns kTRUE in case of success.
497 
498 Bool_t TDirectory::cd(const char *path)
499 {
500  return cd1(path);
501 }
502 
503 ////////////////////////////////////////////////////////////////////////////////
504 /// Change current directory to "this" directory.
505 ///
506 /// Using path one can
507 /// change the current directory to "path". The absolute path syntax is:
508 /// `file.root:/dir1/dir2`
509 /// where `file.root` is the file and `/dir1/dir2` the desired subdirectory
510 /// in the file.
511 ///
512 /// Relative syntax is relative to "this" directory. E.g: `../aa`.
513 ///
514 /// Returns kFALSE in case path does not exist.
515 
516 Bool_t TDirectory::cd1(const char *apath)
517 {
518  Int_t nch = 0;
519  if (apath) nch = strlen(apath);
520  if (!nch) {
521  gDirectory = this;
522  return kTRUE;
523  }
524 
525  TDirectory *where = GetDirectory(apath,kTRUE,"cd");
526  if (where) {
527  where->cd();
528  return kTRUE;
529  }
530  return kFALSE;
531 }
532 
533 ////////////////////////////////////////////////////////////////////////////////
534 /// Change current directory to "path". The absolute path syntax is:
535 /// `file.root:/dir1/dir2`
536 /// where file.root is the file and `/dir1/dir2 the desired subdirectory
537 /// in the file.
538 /// Relative syntax is relative to the current directory `gDirectory`, e.g.: `../aa`.
539 ///
540 /// Returns kTRUE in case of success.
541 
542 Bool_t TDirectory::Cd(const char *path)
543 {
544  return Cd1(path);
545 }
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 /// Change current directory to "path". The path syntax is:
549 /// `file.root:/dir1/dir2`
550 /// where file.root is the file and `/dir1/dir2` the desired subdirectory
551 /// in the file.
552 ///
553 /// Returns kFALSE in case path does not exist.
554 
555 Bool_t TDirectory::Cd1(const char *apath)
556 {
557  // null path is always true (i.e. stay in the current directory)
558  Int_t nch = 0;
559  if (apath) nch = strlen(apath);
560  if (!nch) return kTRUE;
561 
562  TDirectory *where = gDirectory->GetDirectory(apath,kTRUE,"Cd");
563  if (where) {
564  where->cd();
565  return kTRUE;
566  }
567  return kFALSE;
568 }
569 
570 ////////////////////////////////////////////////////////////////////////////////
571 /// Delete all objects from a Directory list.
572 
574 {
575  if (fList) fList->Clear();
576 
577 }
578 
579 ////////////////////////////////////////////////////////////////////////////////
580 /// Delete all objects from memory and directory structure itself.
581 /// if option is "slow", iterate through the containers in a way to can handle
582 /// 'external' modification (induced by recursions)
583 /// if option is "nodelete", write the TDirectory but do not delete the contained
584 /// objects.
586 {
587  if (!fList) {
588  return;
589  }
590 
591  // Save the directory key list and header
592  Save();
593 
594  Bool_t nodelete = option ? (!strcmp(option, "nodelete") ? kTRUE : kFALSE) : kFALSE;
595 
596  if (!nodelete) {
597  Bool_t slow = option ? (!strcmp(option, "slow") ? kTRUE : kFALSE) : kFALSE;
598  if (!slow) {
599  // Check if it is wise to use the fast deletion path.
600  TObjLink *lnk = fList->FirstLink();
601  while (lnk) {
602  if (lnk->GetObject()->IsA() == TDirectory::Class()) {
603  slow = kTRUE;
604  break;
605  }
606  lnk = lnk->Next();
607  }
608  }
609 
610  // Delete objects from directory list, this in turn, recursively closes all
611  // sub-directories (that were allocated on the heap)
612  // if this dir contains subdirs, we must use the slow option for Delete!
613  // we must avoid "slow" as much as possible, in particular Delete("slow")
614  // with a large number of objects (eg >10^5) would take for ever.
615  if (slow) fList->Delete("slow");
616  else fList->Delete();
617  }
618 
620 }
621 
622 ////////////////////////////////////////////////////////////////////////////////
623 /// Delete all objects from memory.
624 
626 {
627  fList->Delete("slow");
628 }
629 
630 ////////////////////////////////////////////////////////////////////////////////
631 /// Delete Objects or/and keys in a directory.
632 ///
633 /// - namecycle has the format name;cycle
634 /// - namecycle = "" same as namecycle ="T*"
635 /// - name = * means all
636 /// - cycle = * means all cycles (memory and keys)
637 /// - cycle = "" or cycle = 9999 ==> apply to a memory object
638 /// When name=* use T* to delete subdirectories also
639 ///
640 /// To delete one directory, you must specify the directory cycle,
641 /// eg. `file.Delete("dir1;1");`
642 ///
643 /// examples:
644 /// - foo : delete object named foo in memory
645 /// - foo* : delete all objects with a name starting with foo
646 /// - foo;1 : delete cycle 1 of foo on file
647 /// - foo;* : delete all cycles of foo on file and also from memory
648 /// - *;2 : delete all objects on file having the cycle 2
649 /// - *;* : delete all objects from memory and file
650 /// - T*;* : delete all objects from memory and file and all subdirectories
651 
652 void TDirectory::Delete(const char *namecycle)
653 {
654  if (gDebug)
655  Info("Delete","Call for this = %s namecycle = %s",
656  GetName(), (namecycle ? namecycle : "null"));
657 
658  TDirectory::TContext ctxt(this);
659  Short_t cycle;
660  char name[kMaxLen];
661  DecodeNameCycle(namecycle, name, cycle, kMaxLen);
662 
663  Int_t deleteall = 0;
664  Int_t deletetree = 0;
665  if(strcmp(name,"*") == 0) deleteall = 1;
666  if(strcmp(name,"*T") == 0){ deleteall = 1; deletetree = 1;}
667  if(strcmp(name,"T*") == 0){ deleteall = 1; deletetree = 1;}
668  if(namecycle==0 || !namecycle[0]){ deleteall = 1; deletetree = 1;}
669  TRegexp re(name,kTRUE);
670  TString s;
671  Int_t deleteOK = 0;
672 
673 //*-*---------------------Case of Object in memory---------------------
674 // ========================
675  if (cycle >= 9999 ) {
676  TNamed *idcur;
677  TIter next(fList);
678  while ((idcur = (TNamed *) next())) {
679  deleteOK = 0;
680  s = idcur->GetName();
681  if (deleteall || s.Index(re) != kNPOS) {
682  deleteOK = 1;
683  if (idcur->IsA() == TDirectory::Class()) {
684  deleteOK = 2;
685  if (!deletetree && deleteall) deleteOK = 0;
686  }
687  }
688  if (deleteOK != 0) {
689  fList->Remove(idcur);
690  if (deleteOK==2) {
691  // read subdirectories to correctly delete them
692  if (deletetree)
693  ((TDirectory*) idcur)->ReadAll("dirs");
694  idcur->Delete(deletetree ? "T*;*" : "*");
695  delete idcur;
696  } else
697  idcur->Delete(name);
698  }
699  }
700  }
701 }
702 
703 ////////////////////////////////////////////////////////////////////////////////
704 /// Fill Graphics Structure and Paint.
705 ///
706 /// Loop on all objects (memory or file) and all subdirectories
707 
709 {
710  fList->R__FOR_EACH(TObject,Draw)(option);
711 }
712 
713 ////////////////////////////////////////////////////////////////////////////////
714 /// Find object in the list of memory objects.
715 
717 {
718  return fList->FindObject(obj);
719 }
720 
721 ////////////////////////////////////////////////////////////////////////////////
722 /// Find object by name in the list of memory objects.
723 
725 {
726  return fList->FindObject(name);
727 }
728 
729 ////////////////////////////////////////////////////////////////////////////////
730 /// Find object by name in the list of memory objects of the current
731 /// directory or its sub-directories.
732 /// After this call the current directory is not changed.
733 /// To automatically set the current directory where the object is found,
734 /// use FindKeyAny(aname)->ReadObj().
735 
736 TObject *TDirectory::FindObjectAny(const char *aname) const
737 {
738  //object may be already in the list of objects in memory
739  TObject *obj = fList->FindObject(aname);
740  if (obj) return obj;
741 
742  //try with subdirectories
743  TIter next(fList);
744  while( (obj = next()) ) {
745  if (obj->IsA()->InheritsFrom(TDirectory::Class())) {
746  TDirectory* subdir = static_cast<TDirectory*>(obj);
747  TObject *subobj = subdir->TDirectory::FindObjectAny(aname); // Explicitly recurse into _this_ exact function.
748  if (subobj) {
749  return subobj;
750  }
751  }
752  }
753  return nullptr;
754 }
755 
756 ////////////////////////////////////////////////////////////////////////////////
757 /// Return pointer to object identified by namecycle.
758 ///
759 /// namecycle has the format name;cycle
760 /// - name = * is illegal, cycle = * is illegal
761 /// - cycle = "" or cycle = 9999 ==> apply to a memory object
762 ///
763 /// examples:
764 /// - foo : get object named foo in memory
765 /// if object is not in memory, try with highest cycle from file
766 /// - foo;1 : get cycle 1 of foo on file
767 ///
768 /// The retrieved object should in principle derive from TObject.
769 /// If not, the function TDirectory::GetObject should be called.
770 /// However, this function will still work for a non-TObject, providing that
771 /// the calling application cast the return type to the correct type (which
772 /// is the actual type of the object).
773 ///
774 /// NOTE:
775 ///
776 /// The method GetObject offer better protection and avoid the need
777 /// for any cast:
778 /// ~~~ {.cpp}
779 /// MyClass *obj;
780 /// directory->GetObject("some object",obj);
781 /// if (obj) { ... the object exist and inherits from MyClass ... }
782 /// ~~~
783 ///
784 /// VERY IMPORTANT NOTE:
785 ///
786 /// In case the class of this object derives from TObject but not
787 /// as a first inheritance, one must use dynamic_cast<>().
788 /// #### Example 1: Normal case:
789 /// ~~~ {.cpp}
790 /// class MyClass : public TObject, public AnotherClass
791 /// ~~~
792 /// then on return, one can do:
793 /// ~~~ {.cpp}
794 /// MyClass *obj = (MyClass*)directory->Get("some object of MyClass");
795 /// ~~~
796 /// #### Example 2: Special case:
797 /// ~~~ {.cpp}
798 /// class MyClass : public AnotherClass, public TObject
799 /// ~~~
800 /// then on return, one must do:
801 /// ~~~ {.cpp}
802 /// MyClass *obj = dynamic_cast<MyClass*>(directory->Get("some object of MyClass"));
803 /// ~~~
804 /// Of course, dynamic_cast<> can also be used in the example 1.
805 
806 TObject *TDirectory::Get(const char *namecycle)
807 {
808  Short_t cycle;
809  char name[kMaxLen];
810 
811  DecodeNameCycle(namecycle, name, cycle, kMaxLen);
812  char *namobj = name;
813  Int_t nch = strlen(name);
814  for (Int_t i = nch-1; i > 0; i--) {
815  if (name[i] == '/') {
816  name[i] = 0;
817  TDirectory* dirToSearch=GetDirectory(name);
818  namobj = name + i + 1;
819  name[i] = '/';
820  return dirToSearch ? dirToSearch->Get(namobj) : nullptr;
821  }
822  }
823 
824 //*-*---------------------Case of Object in memory---------------------
825 // ========================
826  TObject *idcur = fList->FindObject(namobj);
827  if (idcur) {
828  if (idcur==this && strlen(namobj)!=0) {
829  // The object has the same name has the directory and
830  // that's what we picked-up! We just need to ignore
831  // it ...
832  idcur = nullptr;
833  } else if (cycle == 9999) {
834  return idcur;
835  } else {
836  if (idcur->InheritsFrom(TCollection::Class()))
837  idcur->Delete(); // delete also list elements
838  delete idcur;
839  idcur = nullptr;
840  }
841  }
842  return idcur;
843 }
844 
845 ////////////////////////////////////////////////////////////////////////////////
846 /// Return pointer to object identified by namecycle.
847 /// The returned object may or may not derive from TObject.
848 ///
849 /// - namecycle has the format name;cycle
850 /// - name = * is illegal, cycle = * is illegal
851 /// - cycle = "" or cycle = 9999 ==> apply to a memory object
852 ///
853 /// VERY IMPORTANT NOTE:
854 ///
855 /// The calling application must cast the returned object to
856 /// the final type, e.g.
857 /// ~~~ {.cpp}
858 /// MyClass *obj = (MyClass*)directory->GetObject("some object of MyClass");
859 /// ~~~
860 
861 void *TDirectory::GetObjectUnchecked(const char *namecycle)
862 {
863  return GetObjectChecked(namecycle,(TClass *)nullptr);
864 }
865 
866 ////////////////////////////////////////////////////////////////////////////////
867 /// See documentation of TDirectory::GetObjectCheck(const char *namecycle, const TClass *cl)
868 
869 void *TDirectory::GetObjectChecked(const char *namecycle, const char* classname)
870 {
871  return GetObjectChecked(namecycle, TClass::GetClass(classname));
872 }
873 
874 
875 ////////////////////////////////////////////////////////////////////////////////
876 /// Return pointer to object identified by namecycle if and only if the actual
877 /// object is a type suitable to be stored as a pointer to a "expectedClass"
878 /// If expectedClass is null, no check is performed.
879 ///
880 /// namecycle has the format `name;cycle`
881 /// - name = * is illegal, cycle = * is illegal
882 /// - cycle = "" or cycle = 9999 ==> apply to a memory object
883 ///
884 /// VERY IMPORTANT NOTE:
885 ///
886 /// The calling application must cast the returned pointer to
887 /// the type described by the 2 arguments (i.e. cl):
888 /// ~~~ {.cpp}
889 /// MyClass *obj = (MyClass*)directory->GetObjectChecked("some object of MyClass","MyClass"));
890 /// ~~~
891 /// Note: We recommend using the method TDirectory::GetObject:
892 /// ~~~ {.cpp}
893 /// MyClass *obj = nullptr;
894 /// directory->GetObject("some object inheriting from MyClass",obj);
895 /// if (obj) { ... we found what we are looking for ... }
896 /// ~~~
897 
898 void *TDirectory::GetObjectChecked(const char *namecycle, const TClass* expectedClass)
899 {
900  Short_t cycle;
901  char name[kMaxLen];
902 
903  DecodeNameCycle(namecycle, name, cycle, kMaxLen);
904  char *namobj = name;
905  Int_t nch = strlen(name);
906  for (Int_t i = nch-1; i > 0; i--) {
907  if (name[i] == '/') {
908  name[i] = 0;
909  TDirectory* dirToSearch=GetDirectory(name);
910  namobj = name + i + 1;
911  name[i] = '/';
912  if (dirToSearch) {
913  return dirToSearch->GetObjectChecked(namobj, expectedClass);
914  } else {
915  return nullptr;
916  }
917  }
918  }
919 
920 //*-*---------------------Case of Object in memory---------------------
921 // ========================
922  if (!expectedClass || expectedClass->IsTObject()) {
923  TObject *objcur = fList->FindObject(namobj);
924  if (objcur) {
925  if (objcur==this && strlen(namobj)!=0) {
926  // The object has the same name has the directory and
927  // that's what we picked-up! We just need to ignore
928  // it ...
929  objcur = nullptr;
930  } else if (cycle == 9999) {
931  // Check type
932  if (expectedClass && objcur->IsA()->GetBaseClassOffset(expectedClass) == -1) return nullptr;
933  else return objcur;
934  } else {
935  if (objcur->InheritsFrom(TCollection::Class()))
936  objcur->Delete(); // delete also list elements
937  delete objcur;
938  objcur = nullptr;
939  }
940  }
941  }
942 
943  return nullptr;
944 }
945 
946 ////////////////////////////////////////////////////////////////////////////////
947 /// Returns the full path of the directory. E.g. `file:/dir1/dir2`.
948 /// The returned path will be re-used by the next call to GetPath().
949 
950 const char *TDirectory::GetPathStatic() const
951 {
952  static char *path = nullptr;
953  const int kMAXDEPTH = 128;
954  const TDirectory *d[kMAXDEPTH];
955  const TDirectory *cur = this;
956  int depth = 0, len = 0;
957 
958  d[depth++] = cur;
959  len = strlen(cur->GetName()) + 1; // +1 for the /
960 
961  while (cur->fMother && depth < kMAXDEPTH) {
962  cur = (TDirectory *)cur->fMother;
963  d[depth++] = cur;
964  len += strlen(cur->GetName()) + 1;
965  }
966 
967  if (path) delete [] path;
968  path = new char[len+2];
969 
970  for (int i = depth-1; i >= 0; i--) {
971  if (i == depth-1) { // file or TROOT name
972  strlcpy(path, d[i]->GetName(),len+2);
973  strlcat(path, ":",len+2);
974  if (i == 0) strlcat(path, "/",len+2);
975  } else {
976  strlcat(path, "/",len+2);
977  strlcat(path, d[i]->GetName(),len+2);
978  }
979  }
980 
981  return path;
982 }
983 
984 ////////////////////////////////////////////////////////////////////////////////
985 /// Returns the full path of the directory. E.g. `file:/dir1/dir2`.
986 /// The returned path will be re-used by the next call to GetPath().
987 
988 const char *TDirectory::GetPath() const
989 {
991 
992  if (!GetMotherDir()) // case of file
993  fPathBuffer.Append("/");
994 
995  return fPathBuffer.Data();
996 }
997 
998 ////////////////////////////////////////////////////////////////////////////////
999 /// Recursive method to fill full path for directory.
1000 
1002 {
1003  TDirectory* mom = GetMotherDir();
1004  if (mom) {
1005  mom->FillFullPath(buf);
1006  buf += "/";
1007  buf += GetName();
1008  } else {
1009  buf = GetName();
1010  buf += ":";
1011  }
1012 }
1013 
1014 ////////////////////////////////////////////////////////////////////////////////
1015 /// Create a sub-directory "a" or a hierarchy of sub-directories "a/b/c/...".
1016 ///
1017 /// Returns 0 in case of error or if a sub-directory (hierarchy) with the requested
1018 /// name already exists.
1019 /// returnExistingDirectory returns a pointer to an already existing sub-directory with the same name.
1020 /// Returns a pointer to the created sub-directory or to the top sub-directory of
1021 /// the hierarchy (in the above example, the returned TDirectory * always points
1022 /// to "a").
1023 /// In particular, the steps to create first a/b/c and then a/b/d without receiving
1024 /// errors are:
1025 /// ~~~ {.cpp}
1026 /// TFile * file = new TFile("afile","RECREATE");
1027 /// file->mkdir("a");
1028 /// file->cd("a");
1029 /// gDirectory->mkdir("b/c");
1030 /// gDirectory->cd("b");
1031 /// gDirectory->mkdir("d");
1032 /// ~~~
1033 /// or
1034 /// ~~~ {.cpp}
1035 /// TFile * file = new TFile("afile","RECREATE");
1036 /// file->mkdir("a");
1037 /// file->cd("a");
1038 /// gDirectory->mkdir("b/c");
1039 /// gDirectory->mkdir("b/d", "", true);
1040 /// ~~~
1041 
1042 TDirectory *TDirectory::mkdir(const char *name, const char *title, Bool_t returnExistingDirectory)
1043 {
1044  if (returnExistingDirectory) {
1045  auto existingdir = GetDirectory(name);
1046  if (existingdir)
1047  return existingdir;
1048  }
1049  if (!name || !title || !name[0]) return nullptr;
1050  if (!title[0]) title = name;
1051  TDirectory *newdir = nullptr;
1052  if (const char *slash = strchr(name,'/')) {
1053  Long_t size = Long_t(slash-name);
1054  char *workname = new char[size+1];
1055  strncpy(workname, name, size);
1056  workname[size] = 0;
1057  TDirectory *tmpdir;
1058  GetObject(workname,tmpdir);
1059  if (!tmpdir)
1060  tmpdir = mkdir(workname,title);
1061  delete[] workname;
1062  if (!tmpdir) return nullptr;
1063  if (!newdir) newdir = tmpdir;
1064  return tmpdir->mkdir(slash+1);
1065  }
1066 
1067  TDirectory::TContext ctxt(this);
1068 
1069  newdir = new TDirectory(name, title, "", this);
1070 
1071  return newdir;
1072 }
1073 
1074 ////////////////////////////////////////////////////////////////////////////////
1075 /// List Directory contents.
1076 ///
1077 /// Indentation is used to identify the directory tree
1078 /// Subdirectories are listed first, then objects in memory.
1079 ///
1080 /// The option can has the following format:
1081 ///
1082 /// [<regexp>]
1083 ///
1084 /// The `<regexp>` will be used to match the name of the objects.
1085 /// By default memory and disk objects are listed.
1086 
1087 void TDirectory::ls(Option_t *option) const
1088 {
1091 
1092  TString opta = option;
1093  TString opt = opta.Strip(TString::kBoth);
1094  Bool_t memobj = kTRUE;
1095  TString reg = "*";
1096  if (opt.BeginsWith("-m")) {
1097  if (opt.Length() > 2)
1098  reg = opt(2,opt.Length());
1099  } else if (opt.BeginsWith("-d")) {
1100  memobj = kFALSE;
1101  if (opt.Length() > 2)
1102  reg = opt(2,opt.Length());
1103  } else if (!opt.IsNull())
1104  reg = opt;
1105 
1106  TRegexp re(reg, kTRUE);
1107 
1108  if (memobj) {
1109  TObject *obj;
1110  TIter nextobj(fList);
1111  while ((obj = (TObject *) nextobj())) {
1112  TString s = obj->GetName();
1113  if (s.Index(re) == kNPOS) continue;
1114  obj->ls(option); //*-* Loop on all the objects in memory
1115  }
1116  }
1118 }
1119 
1120 ////////////////////////////////////////////////////////////////////////////////
1121 /// Paint all objects in the directory.
1122 
1124 {
1125  fList->R__FOR_EACH(TObject,Paint)(option);
1126 }
1127 
1128 ////////////////////////////////////////////////////////////////////////////////
1129 /// Print all objects in the directory.
1130 
1131 void TDirectory::Print(Option_t *option) const
1132 {
1133  fList->R__FOR_EACH(TObject,Print)(option);
1134 }
1135 
1136 ////////////////////////////////////////////////////////////////////////////////
1137 /// Print the path of the directory.
1138 
1139 void TDirectory::pwd() const
1140 {
1141  Printf("%s", GetPath());
1142 }
1143 
1144 ////////////////////////////////////////////////////////////////////////////////
1145 /// Recursively remove object from a Directory.
1146 
1148 {
1149  fList->RecursiveRemove(obj);
1150 }
1151 
1152 ////////////////////////////////////////////////////////////////////////////////
1153 /// Remove an object from the in-memory list.
1154 
1156 {
1157  TObject *p = 0;
1158  if (fList) {
1159  p = fList->Remove(obj);
1160  }
1161  return p;
1162 }
1163 
1164 ////////////////////////////////////////////////////////////////////////////////
1165 /// Removes subdirectory from the directory
1166 /// When directory is deleted, all keys in all subdirectories will be
1167 /// read first and deleted from file (if exists)
1168 /// Equivalent call is Delete("name;*");
1169 
1170 void TDirectory::rmdir(const char *name)
1171 {
1172  if ((name==0) || (*name==0)) return;
1173 
1174  TString mask(name);
1175  mask+=";*";
1176  Delete(mask);
1177 }
1178 
1179 ////////////////////////////////////////////////////////////////////////////////
1180 /// Save object in filename,
1181 /// if filename is 0 or "", a file with "objectname.root" is created.
1182 /// The name of the key is the object name.
1183 /// If the operation is successful, it returns the number of bytes written to the file
1184 /// otherwise it returns 0.
1185 /// By default a message is printed. Use option "q" to not print the message.
1186 /// If filename contains ".json" extension, JSON representation of the object
1187 /// will be created and saved in the text file. Such file can be used in
1188 /// JavaScript ROOT (https://root.cern.ch/js/) to display object in web browser
1189 /// When creating JSON file, option string may contain compression level from 0 to 3 (default 0)
1190 
1191 Int_t TDirectory::SaveObjectAs(const TObject *obj, const char *filename, Option_t *option) const
1192 {
1193  if (!obj) return 0;
1194  Int_t nbytes = 0;
1195  TString fname = filename;
1196  if (!filename || !filename[0]) {
1197  fname.Form("%s.root",obj->GetName());
1198  }
1199  TString cmd;
1200  if (fname.Index(".json") > 0) {
1201  cmd.Form("TBufferJSON::ExportToFile(\"%s\",(TObject*) %s, \"%s\");", fname.Data(), TString::LLtoa((Long_t)obj, 10).Data(), (option ? option : ""));
1202  nbytes = gROOT->ProcessLine(cmd);
1203  } else {
1204  cmd.Form("TFile::Open(\"%s\",\"recreate\");",fname.Data());
1205  TContext ctxt; // The TFile::Open will change the current directory.
1206  TDirectory *local = (TDirectory*)gROOT->ProcessLine(cmd);
1207  if (!local) return 0;
1208  nbytes = obj->Write();
1209  delete local;
1210  }
1211  TString opt(option);
1212  opt.ToLower();
1213  if (!opt.Contains("q")) {
1214  if (!gSystem->AccessPathName(fname.Data())) obj->Info("SaveAs", "ROOT file %s has been created", fname.Data());
1215  }
1216  return nbytes;
1217 }
1218 
1219 ////////////////////////////////////////////////////////////////////////////////
1220 /// Set the name for directory
1221 /// If the directory name is changed after the directory was written once,
1222 /// ROOT currently would NOT change the name of correspondent key in the
1223 /// mother directory.
1224 /// DO NOT use this method to 'rename a directory'.
1225 /// Renaming a directory is currently NOT supported.
1226 
1227 void TDirectory::SetName(const char* newname)
1228 {
1229  TNamed::SetName(newname);
1230 }
1231 
1232 ////////////////////////////////////////////////////////////////////////////////
1233 /// Encode the name and cycle into buffer like: "aap;2".
1234 
1235 void TDirectory::EncodeNameCycle(char *buffer, const char *name, Short_t cycle)
1236 {
1237  if (cycle == 9999)
1238  strcpy(buffer, name);
1239  else
1240  sprintf(buffer, "%s;%d", name, cycle);
1241 }
1242 
1243 ////////////////////////////////////////////////////////////////////////////////
1244 /// Decode a namecycle "aap;2" into name "aap" and cycle "2". Destination
1245 /// buffer size for name (including string terminator) should be specified in
1246 /// namesize.
1247 
1248 void TDirectory::DecodeNameCycle(const char *buffer, char *name, Short_t &cycle,
1249  const size_t namesize)
1250 {
1251  size_t len = 0;
1252  const char *ni = strchr(buffer, ';');
1253 
1254  if (ni) {
1255  // Found ';'
1256  len = ni - buffer;
1257  ++ni;
1258  } else {
1259  // No ';' found
1260  len = strlen(buffer);
1261  ni = &buffer[len];
1262  }
1263 
1264  if (namesize) {
1265  if (len > namesize-1ul) len = namesize-1; // accommodate string terminator
1266  } else {
1267  ::Warning("TDirectory::DecodeNameCycle",
1268  "Using unsafe version: invoke this metod by specifying the buffer size");
1269  }
1270 
1271  strncpy(name, buffer, len);
1272  name[len] = '\0';
1273 
1274  if (*ni == '*')
1275  cycle = 10000;
1276  else if (isdigit(*ni)) {
1277  long parsed = strtol(ni,nullptr,10);
1278  if (parsed >= (long) std::numeric_limits<Short_t>::max())
1279  cycle = 0;
1280  else
1281  cycle = (Short_t)parsed;
1282  } else
1283  cycle = 9999;
1284 }
1285 
1286 ////////////////////////////////////////////////////////////////////////////////
1287 /// Register a TContext pointing to this TDirectory object
1288 
1291 
1292  if (fContext) {
1293  TContext *current = fContext;
1294  while(current->fNext) {
1295  current = current->fNext;
1296  }
1297  current->fNext = ctxt;
1298  ctxt->fPrevious = current;
1299  } else {
1300  fContext = ctxt;
1301  }
1302 }
1303 
1304 ////////////////////////////////////////////////////////////////////////////////
1305 /// \copydoc TDirectory::WriteTObject().
1306 
1307 Int_t TDirectory::WriteTObject(const TObject *obj, const char *name, Option_t * /*option*/, Int_t /*bufsize*/)
1308 {
1309  const char *objname = "no name specified";
1310  if (name) objname = name;
1311  else if (obj) objname = obj->GetName();
1312  Error("WriteTObject","The current directory (%s) is not associated with a file. The object (%s) has not been written.",GetName(),objname);
1313  return 0;
1314 }
1315 
1316 ////////////////////////////////////////////////////////////////////////////////
1317 /// UnRegister a TContext pointing to this TDirectory object
1318 
1320 
1322 
1323  // Another thread already unregistered the TContext.
1324  if (ctxt->fDirectory == nullptr)
1325  return;
1326 
1327  if (ctxt==fContext) {
1328  fContext = ctxt->fNext;
1329  if (fContext) fContext->fPrevious = nullptr;
1330  ctxt->fPrevious = ctxt->fNext = nullptr;
1331  } else {
1332  TContext *next = ctxt->fNext;
1333  ctxt->fPrevious->fNext = next;
1334  if (next) next->fPrevious = ctxt->fPrevious;
1335  ctxt->fPrevious = ctxt->fNext = nullptr;
1336  }
1337 }
1338 
1339 ////////////////////////////////////////////////////////////////////////////////
1340 /// TDirectory Streamer.
1341 void TDirectory::Streamer(TBuffer &R__b)
1342 {
1343  // Stream an object of class TDirectory.
1344 
1345  UInt_t R__s, R__c;
1346  if (R__b.IsReading()) {
1347  Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
1348  TNamed::Streamer(R__b);
1349  R__b >> fMother;
1350  R__b >> fList;
1351  fList->UseRWLock();
1352  fUUID.Streamer(R__b);
1353  R__b.CheckByteCount(R__s, R__c, TDirectory::IsA());
1354  } else {
1355  R__c = R__b.WriteVersion(TDirectory::IsA(), kTRUE);
1356  TNamed::Streamer(R__b);
1357  R__b << fMother;
1358  R__b << fList;
1359  fUUID.Streamer(R__b);
1360  R__b.SetByteCount(R__c, kTRUE);
1361  }
1362 }
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:708
TDirectory::Remove
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
Definition: TDirectory.cxx:1155
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:652
TDirectory::GetList
virtual TList * GetList() const
Definition: TDirectory.h:167
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:1042
TDirectory::fPathBuffer
TString fPathBuffer
Definition: TDirectory.h:98
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:170
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:1106
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:950
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:1248
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:157
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:51
TDirectory::RegisterContext
void RegisterContext(TContext *ctxt)
Register a TContext pointing to this TDirectory object.
Definition: TDirectory.cxx:1289
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:555
TDirectory::UnregisterContext
void UnregisterContext(TContext *ctxt)
UnRegister a TContext pointing to this TDirectory object.
Definition: TDirectory.cxx:1319
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:47
TClass.h
TDirectory::WriteTObject
virtual Int_t WriteTObject(const TObject *obj, const char *name=nullptr, Option_t *="", Int_t=0)
Definition: TDirectory.cxx:1307
TDirectory::cd
virtual Bool_t cd(const char *path=nullptr)
Change current directory to "this" directory.
Definition: TDirectory.cxx:498
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:1170
TBuffer
Buffer base class used for serializing objects.
Definition: TBuffer.h:43
TDirectory::fContext
TContext * fContext
Buffer for GetPath() function.
Definition: TDirectory.h:99
TDirectory::FillFullPath
void FillFullPath(TString &buf) const
Recursive method to fill full path for directory.
Definition: TDirectory.cxx:1001
TDirectory::fUUID
TUUID fUUID
Definition: TDirectory.h:97
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:1139
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:1131
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:806
bool
TDirectory::TContext::fDirectory
std::atomic< TDirectory * > fDirectory
Definition: TDirectory.h:49
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:53
TDirectory::Close
virtual void Close(Option_t *option="")
Delete all objects from memory and directory structure itself.
Definition: TDirectory.cxx:585
TString::kBoth
@ kBoth
Definition: TString.h:267
TBuffer::ResetMap
virtual void ResetMap()=0
TROOT.h
TDirectory::Save
virtual void Save()
Definition: TDirectory.h:197
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:542
TString::Form
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
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:1235
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:329
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:96
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
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:573
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:1147
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:301
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:869
gDirectory
#define gDirectory
Definition: TDirectory.h:236
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:401
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:2931
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:95
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:5809
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:988
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:1087
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:2077
TDirectory::cd1
Bool_t cd1(const char *path)
flag to add histograms, graphs,etc to the directory
Definition: TDirectory.cxx:516
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:165
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:40
TDirectory::Paint
void Paint(Option_t *option="") override
Paint all objects in the directory.
Definition: TDirectory.cxx:1123
TDirectory::GetObjectUnchecked
virtual void * GetObjectUnchecked(const char *namecycle)
Return pointer to object identified by namecycle.
Definition: TDirectory.cxx:861
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:104
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:736
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:1227
Class
void Class()
Definition: Class.C:29
TString::ToLower
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1125
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::fSpinLock
std::atomic_flag fSpinLock
Counter delaying the TDirectory destructor from finishing.
Definition: TDirectory.h:102
TDirectory::FindObject
TObject * FindObject(const char *name) const override
Find object by name in the list of memory objects.
Definition: TDirectory.cxx:724
TDirectory::DeleteAll
virtual void DeleteAll(Option_t *option="")
Delete all objects from memory.
Definition: TDirectory.cxx:625
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:52
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::CurrentDirectory
static TDirectory *& CurrentDirectory()
Return the current directory for the current thread.
Definition: TDirectory.cxx:381
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:1191