39 thread_local std::atomic_flag gDirectory_lock = ATOMIC_FLAG_INIT;
40 return &gDirectory_lock;
78 if (!initMotherDir) initMotherDir =
gDirectory;
80 if (strchr(
name,
'/')) {
81 ::Error(
"TDirectory::TDirectory",
"directory name (%s) cannot contain a slash",
name);
86 ::Error(
"TDirectory::TDirectory",
"directory name cannot be \"\"");
107 if (!
fList->IsUsingRWLock())
108 Fatal(
"~TDirectory",
"In %s:%p the fList (%p) is not using the RWLock\n",
110 fList->Delete(
"slow");
123 Info(
"~TDirectory",
"dtor called for %s",
GetName());
149 (*fDirectory).UnregisterContext(
this);
167#pragma warning(disable : 4996)
169#pragma GCC diagnostic push
170#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
177void TDirectory::AddDirectory(
Bool_t add)
186Bool_t TDirectory::AddDirectoryStatus()
194#pragma GCC diagnostic pop
205 if (!obj || !
fList)
return;
211 Warning(
"Append",
"Replacing existing %s: %s (Potential memory leak).", obj->
IsA()->
GetName(),
242 while ((obj = nextin())) {
264 if (motherDir && strlen(
GetName()) != 0) motherDir->
Append(
this);
272 std::vector<TContext*> extraWait;
280 ctxt->fDirectoryWait =
true;
287 ctxt->fDirectory =
nullptr;
289 if (ctxt->fActiveDestructor) {
292 ctxt->fDirectoryWait =
false;
304 if (ptr->load() ==
this) {
306 if (!next || next ==
this) {
320 ptr->compare_exchange_strong(This, next);
324 for(
auto &&context : extraWait) {
327 while(context->fActiveDestructor);
329 context->fDirectoryWait =
false;
354 void *args[] = { &mode, &
size };
356 creator(
nullptr,2,args,&result);
373 char *pobj = (
char*)obj->
IsA()->
New();
375 Fatal(
"CloneObject",
"Failed to create new object");
380 if (baseOffset==-1) {
384 Fatal(
"CloneObject",
"Incorrect detection of the inheritance from TObject for class %s.\n",
394 Fatal(
"CloneObject",
"Not able to create a TBuffer!");
429 thread_local shared_ptr_type currentDirectory =
432 return currentDirectory;
455 Bool_t printError,
const char *funcname)
458 if (apath) nch = strlen(apath);
463 if (funcname==
nullptr || strlen(funcname)==0) funcname =
"GetDirectory";
467 char *path =
new char[nch+1]; path[0] = 0;
468 if (nch) strlcpy(path,apath,nch+1);
469 char *s = (
char*)strrchr(path,
':');
478 if (s && *(s+1)) result =
f->GetDirectory(s+1,printError,funcname);
479 delete [] path;
return result;
481 if (printError)
Error(funcname,
"No such file %s", path);
482 delete [] path;
return nullptr;
487 if (path[0] ==
'/') {
490 delete [] path;
return result;
494 char *
slash = (
char*)strchr(path,
'/');
496 if (!strcmp(path,
"..")) {
498 delete [] path;
return result;
502 if (printError)
Error(funcname,
"Unknown directory %s", path);
503 delete [] path;
return nullptr;
508 if (printError)
Error(funcname,
"Object %s is not a directory", path);
509 delete [] path;
return nullptr;
515 slash = (
char*)strchr(subdir.
Data(),
'/');
518 if (!strcmp(subdir,
"..")) {
522 delete [] path;
return result;
526 if (printError)
Error(funcname,
"Unknown directory %s", subdir.
Data());
527 delete [] path;
return nullptr;
532 if (printError)
Error(funcname,
"Object %s is not a directory", subdir.
Data());
533 delete [] path;
return nullptr;
536 delete [] path;
return result;
550 thread_local_gdirectory->exchange(
this);
589 if (!apath || !apath[0])
626 if (!apath || !apath[0])
681 if (slow)
fList->Delete(
"slow");
682 else fList->Delete();
693 fList->Delete(
"slow");
721 Info(
"Delete",
"Call for this = %s namecycle = %s",
722 GetName(), (namecycle ? namecycle :
"null"));
730 Int_t deletetree = 0;
731 if(strcmp(
name,
"*") == 0) deleteall = 1;
732 if(strcmp(
name,
"*T") == 0){ deleteall = 1; deletetree = 1;}
733 if(strcmp(
name,
"T*") == 0){ deleteall = 1; deletetree = 1;}
734 if(namecycle==
nullptr || !namecycle[0]){ deleteall = 1; deletetree = 1;}
741 if (cycle >= 9999 ) {
744 while ((idcur = (
TNamed *) next())) {
751 if (!deletetree && deleteall) deleteOK = 0;
755 fList->Remove(idcur);
760 idcur->
Delete(deletetree ?
"T*;*" :
"*");
784 return fList->FindObject(obj);
810 while( (obj = next()) ) {
813 TObject *subobj = subdir->TDirectory::FindObjectAny(aname);
880 for (
Int_t i = nch-1; i > 0; i--) {
881 if (
name[i] ==
'/') {
884 namobj =
name + i + 1;
886 return dirToSearch ? dirToSearch->
Get(namobj) :
nullptr;
894 if (idcur==
this && strlen(namobj)!=0) {
899 }
else if (cycle == 9999) {
972 for (
Int_t i = nch-1; i > 0; i--) {
973 if (
name[i] ==
'/') {
976 namobj =
name + i + 1;
988 if (!expectedClass || expectedClass->
IsTObject()) {
991 if (objcur==
this && strlen(namobj)!=0) {
996 }
else if (cycle == 9999) {
1018 static char *path =
nullptr;
1019 const int kMAXDEPTH = 128;
1022 int depth = 0, len = 0;
1025 len = strlen(cur->
GetName()) + 1;
1027 while (cur->
fMother && depth < kMAXDEPTH) {
1030 len += strlen(cur->
GetName()) + 1;
1033 if (path)
delete [] path;
1034 path =
new char[len+2];
1036 for (
int i = depth-1; i >= 0; i--) {
1038 strlcpy(path,
d[i]->
GetName(),len+2);
1039 strlcat(path,
":",len+2);
1040 if (i == 0) strlcat(path,
"/",len+2);
1042 strlcat(path,
"/",len+2);
1043 strlcat(path,
d[i]->
GetName(),len+2);
1114 if (returnExistingDirectory) {
1119 if (!
name || !title || !
name[0])
return nullptr;
1120 if (!title[0]) title =
name;
1121 if (
const char *
slash = strchr(
name,
'/')) {
1123 char *workname =
new char[
size+1];
1129 tmpdir =
mkdir(workname,title);
1131 if (!tmpdir)
return nullptr;
1164 reg = opt(2,opt.
Length());
1168 reg = opt(2,opt.
Length());
1169 }
else if (!opt.
IsNull())
1177 while ((obj = (
TObject *) nextobj())) {
1216 fList->RecursiveRemove(obj);
1226 p =
fList->Remove(obj);
1239 if ((
name==
nullptr) || (*
name==0))
return;
1266 TString fname, opt = option, cmd;
1267 if (filename && *filename)
1273 if (fname.
Index(
".json") > 0) {
1274 cmd.Form(
"TBufferJSON::ExportToFile(\"%s\", (TObject *) 0x%zx, \"%s\");", fname.
Data(), (
size_t) obj, (option ? option :
""));
1275 nbytes =
gROOT->ProcessLine(cmd);
1277 cmd.Form(
"TFile::Open(\"%s\",\"%s\");", fname.
Data(), opt.
Contains(
"a") ?
"update" :
"recreate");
1280 if (!local)
return 0;
1281 nbytes = obj->
Write();
1285 obj->
Info(
"SaveAs",
"ROOT file %s has been created", fname.
Data());
1325 int semicolonIdx = -1;
1327 char ch = buffer[nameLen];
1330 semicolonIdx = nameLen;
1334 ch = buffer[nameLen];
1337 assert(semicolonIdx == -1 || semicolonIdx ==
static_cast<int>(nameLen));
1340 size_t truncatedNameLen = nameLen;
1343 truncatedNameLen = std::min(truncatedNameLen, namesize - 1);
1345 ::Error(
"TDirectory::DecodeNameCycle",
1346 "Using unsafe version: invoke this method by specifying the buffer size");
1349 strncpy(
name, buffer, truncatedNameLen);
1350 name[truncatedNameLen] =
'\0';
1353 if (semicolonIdx < 0) {
1359 const char *cycleStr = buffer + semicolonIdx + 1;
1361 if (cycleStr[0] ==
'*') {
1363 }
else if (isdigit(cycleStr[0])) {
1364 long parsed = strtol(cycleStr,
nullptr, 10);
1365 if (parsed >=
static_cast<long>(std::numeric_limits<Short_t>::max()))
1368 cycle =
static_cast<Short_t>(parsed);
1387 if (!current || !current->
IsBuilt())
1399 ROOT::Internal::TSpinLockGuard slg(
fSpinLock);
1405 while(current->fNext) {
1406 current = current->fNext;
1408 current->fNext = ctxt;
1409 ctxt->fPrevious = current;
1420 ROOT::Internal::TSpinLockGuard slg(
fSpinLock);
1434 const char *objname =
"no name specified";
1437 Error(
"WriteTObject",
"The current directory (%s) is not associated with a file. The object (%s) has not been written.",
GetName(),objname);
1477 fUUID.Streamer(R__b);
1484 fUUID.Streamer(R__b);
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Signed integer 4 bytes (int).
short Version_t
Class version identifier (short).
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
bool Bool_t
Boolean (0=false, 1=true) (bool).
short Short_t
Signed Short integer 2 bytes (short).
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
const char Option_t
Option string (const char).
void(* tcling_callfunc_Wrapper_t)(void *, int, void **, void *)
static std::atomic_flag * GetCurrentDirectoryLock()
static TBuffer * R__CreateBuffer()
Fast execution of 'new TBufferFile(TBuffer::kWrite,10000), without having a compile time circular dep...
externTVirtualMutex * gROOTMutex
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
#define R__LOCKGUARD(mutex)
A spin mutex-as-code-guard class.
Using a TBrowser one can browse all ROOT objects.
Buffer base class used for serializing objects.
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
virtual void ResetMap()=0
void SetBufferOffset(Int_t offset=0)
void SetReadMode()
Set buffer in read mode.
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
virtual void MapObject(const TObject *obj, UInt_t offset=1)=0
TClass instances represent classes, structs and namespaces in the ROOT type system.
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
ROOT::DirAutoAdd_t GetDirectoryAutoAdd() const
Return the wrapper around the directory auto add function.
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Int_t GetBaseClassOffset(const TClass *toBase, void *address=nullptr, bool isDerivedObject=true)
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.
TDirectory::TContext keeps track and restore the current directory.
std::atomic< bool > fDirectoryWait
! Set to true if a TDirectory might still access this object.
void RegisterCurrentDirectory()
void CdNull()
Set the current directory to null.
TContext * fPrevious
! Pointer to the next TContext in the implied list of context pointing to fPrevious.
std::atomic< bool > fActiveDestructor
! Set to true during the destructor execution
TContext * fNext
! Pointer to the next TContext in the implied list of context pointing to fPrevious.
std::atomic< TDirectory * > fDirectory
! Pointer to the previous current directory.
Bool_t cd1(const char *path)
Change current directory to "this" directory or to the directory described by the path if given one.
void Delete(const char *namecycle="") override
Delete Objects or/and keys in a directory.
virtual void Close(Option_t *option="")
Delete all objects from memory and directory structure itself.
static Bool_t Cd(const char *path)
virtual TList * GetList() const
TDirectory(const TDirectory &directory)=delete
std::shared_ptr< std::atomic< TDirectory * > > SharedGDirectory_t
virtual TDirectory * GetDirectory(const char *namecycle, Bool_t printError=false, const char *funcname="GetDirectory")
Find a directory using apath.
virtual Int_t WriteTObject(const TObject *obj, const char *name=nullptr, Option_t *="", Int_t=0)
virtual const char * GetPath() const
Returns the full path of the directory.
std::atomic_flag fSpinLock
! MSVC doesn't support = ATOMIC_FLAG_INIT;
virtual TObject * Get(const char *namecycle)
Return pointer to object identified by namecycle.
virtual void * GetObjectUnchecked(const char *namecycle)
Return pointer to object identified by namecycle.
void Draw(Option_t *option="") override
Fill Graphics Structure and Paint.
virtual void DeleteAll(Option_t *option="")
Delete all objects from memory.
std::atomic< size_t > fContextPeg
! Counter delaying the TDirectory destructor from finishing.
std::vector< SharedGDirectory_t > fGDirectories
! thread local gDirectory pointing to this object.
virtual void rmdir(const char *name)
Removes subdirectory from the directory When directory is deleted, all keys in all subdirectories wil...
void FillFullPath(TString &buf) const
Recursive method to fill full path for directory.
void CleanTargets()
Clean the pointers to this object (gDirectory, TContext, etc.).
void ls(Option_t *option="") const override
List Directory contents.
TContext * fContext
! Pointer to a list of TContext object pointing to this TDirectory
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
void RegisterGDirectory(SharedGDirectory_t &ptr)
TDirectory()
Directory default constructor.
void Clear(Option_t *option="") override
Delete all objects from a Directory list.
virtual TFile * GetFile() const
TObject * FindObject(const char *name) const override
Find object by name in the list of memory objects.
void Print(Option_t *option="") const override
Print all objects in the directory.
virtual Bool_t cd()
Change current directory to "this" directory.
static size_t DecodeNameCycle(const char *namecycle, char *name, Short_t &cycle, const size_t namesize=0)
virtual ~TDirectory()
Destructor.
static Bool_t Cd1(const char *path)
Change current directory to "path".
void UnregisterContext(TContext *ctxt)
UnRegister a TContext pointing to this TDirectory object.
void Streamer(TBuffer &) override
TDirectory Streamer.
void RecursiveRemove(TObject *obj) override
Recursively remove object from a Directory.
virtual Int_t SaveObjectAs(const TObject *, const char *="", Option_t *="") const
Save object in filename, if filename is nullptr or "", a file with "<objectname>.root" is created.
TString fPathBuffer
! Buffer for GetPath() function
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/...".
void SetName(const char *newname) override
Set the name for directory If the directory name is changed after the directory was written once,...
void BuildDirectory(TFile *motherFile, TDirectory *motherDir)
Initialise directory to defaults.
static SharedGDirectory_t & GetSharedLocalCurrentDirectory()
Return the (address of) a shared pointer to the struct holding the actual thread local gDirectory poi...
TUUID fUUID
Unique identifier.
static Bool_t fgAddDirectory
!
TDirectory * GetMotherDir() const
virtual const char * GetPathStatic() const
Returns the full path of the directory.
static std::atomic< TDirectory * > & CurrentDirectory()
Return the current directory for the current thread.
TClass * IsA() const override
TObject * fMother
pointer to mother of the directory
void Browse(TBrowser *b) override
Browse the content of the directory.
void GetObject(const char *namecycle, T *&ptr)
Get an object with proper type checking.
virtual void pwd() const
Print the path of the directory.
virtual void * GetObjectChecked(const char *namecycle, const char *classname)
See documentation of TDirectory::GetObjectCheck(const char *namecycle, const TClass *cl).
virtual TObject * CloneObject(const TObject *obj, Bool_t autoadd=kTRUE)
Clone an object.
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
void RegisterContext(TContext *ctxt)
TList * fList
List of objects in memory.
void Paint(Option_t *option="") override
Paint all objects in the directory.
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.
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
THashList implements a hybrid collection class consisting of a hash table and a list to store TObject...
Each ROOT class (see TClass) has a linked list of methods.
const char * GetName() const override
Returns name of object.
void Streamer(TBuffer &) override
Stream an object of class TObject.
virtual void SetName(const char *name)
Set the name of the TNamed.
TClass * IsA() const override
Wrapper around a TObject so it can be stored in a TList.
TObject * GetObject() const
Mother of all ROOT objects.
virtual const char * GetName() const
Returns name of object.
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
virtual void Delete(Option_t *option="")
Delete this object.
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
virtual TClass * IsA() const
TObject()
TObject constructor.
virtual void ls(Option_t *option="") const
The ls function lists the contents of a class on stdout.
@ kCanDelete
if object in a list can be deleted
@ kIsReferenced
if object is referenced by a TRef or TRefArray
@ kMustCleanup
if object destructor must call RecursiveRemove()
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Regular expression class.
void ToLower()
Change string to lower-case.
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
const char * Data() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
void(* DirAutoAdd_t)(void *, TDirectory *)