<commit_before>// @(#)root/base:$Name:  $:$Id: TDirectory.cxx,v 1.29 2002/08/02 18:54:37 rdm Exp $
// Author: <NAME>   28/11/94

/*************************************************************************
 * Copyright (C) 1995-2000, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "Strlen.h"
#include "TDirectory.h"
#include "TMapFile.h"
#include "TClassTable.h"
#include "TInterpreter.h"
#include "THashList.h"
#include "TBrowser.h"
#include "TFree.h"
#include "TKey.h"
#include "TROOT.h"
#include "TError.h"
#include "Bytes.h"
#include "TStreamerInfo.h"
#include "TRegexp.h"
#include "TProcessUUID.h"

TDirectory    *gDirectory;      //Pointer to current directory in memory

//______________________________________________________________________________
//Begin_Html
/*
<img src="gif/tdirectory_classtree.gif">
*/
//End_Html

ClassImp(TDirectory)

//______________________________________________________________________________
//
// A ROOT file is structured in Directories (like a file system).
// Each Directory has a list of Keys (see TKeys) and a list of objects
// in memory. A Key is a small object that describes the type and location
// of a persistent object in a file. The persistent object may be a directory.
//Begin_Html
/*
<img src="gif/fildir.gif">
*/
//End_Html
//
//      The structure of a file is shown in TFile::TFile
//

//______________________________________________________________________________
TDirectory::TDirectory() : TNamed()
{
//*-*-*-*-*-*-*-*-*-*-*-*Directory default constructor-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                    =============================
   fFile = 0;
   fList = 0;
   fKeys = 0;
   fWritable = kFALSE;
}

//______________________________________________________________________________
TDirectory::TDirectory(const char *name, const char *title, Option_t *classname)
           : TNamed(name, title)
{
//*-*-*-*-*-*-*-*-*-*-*-* Create a new Directory *-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                     ======================
//  A new directory with name,title is created in the current directory
//  The directory header information is immediatly saved on the file
//  A new key is added in the parent directory
//
//  When this constructor is called from a class directly derived
//  from TDirectory, the third argument classname MUST be specified.
//  In this case, classname must be the name of the derived class.
//
//  Note that the directory name cannot contain slashes.
//
   if (strchr(name,'/')) {
      ::Error("TDirectory::TDirectory","directory name cannot contain a slash", name);
      gDirectory = 0;
      return;
   }
   if (strlen(GetName()) == 0) {
      ::Error("TDirectory::TDirectory","directory name cannot be \"\"");
      gDirectory = 0;
      return;
   }

   Build();
   if (gDirectory == 0) return;
   if (gFile == 0) return;
   if (!gFile->IsWritable()) return; //*-* in case of a directory in memory
   if (gDirectory->GetKey(name)) {
      Error("TDirectory","Directory %s exists already",name);
      return;
   }
   TClass *cl = IsA();
   if (strlen(classname) != 0) cl = gROOT->GetClass(classname);
   if (!cl) {
      Error("TDirectory","Invalid class name: %s",classname);
      return;
   }
   fWritable    = kTRUE;
   fSeekParent  = gFile->GetSeekDir();
   Int_t nbytes = TDirectory::Sizeof();
   TKey *key    = new TKey(fName,fTitle,cl,nbytes);
   fNbytesName  = key->GetKeylen();
   fSeekDir     = key->GetSeekKey();
   if (fSeekDir == 0) return;
   char *buffer = key->GetBuffer();
   TDirectory::FillBuffer(buffer);
   Int_t cycle = gDirectory->AppendKey(key);
   key->WriteFile(cycle);
   fModified = kFALSE;
   gROOT->GetUUIDs()->AddUUID(fUUID,this);
}

//______________________________________________________________________________
TDirectory::TDirectory(const TDirectory &directory) : TNamed(directory)
{
   ((TDirectory&)directory).Copy(*this);
}

//______________________________________________________________________________
TDirectory::~TDirectory()
{
//*-*-*-*-*-*-*-*-*-*-*-*Directory destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                    ====================

   if (gROOT == 0) return; //when called by TROOT destructor

   TCollection::StartGarbageCollection();

   if (fList) {
      SetBit(kCloseDirectory);
      fList->Delete();
      SafeDelete(fList);
   }
   if (fKeys) {
      fKeys->Delete();
      SafeDelete(fKeys);
   }

   TCollection::EmptyGarbageCollection();

   if (gDebug)
      cerr << "TDirectory dtor called for "<< GetName() << endl;
}

//______________________________________________________________________________
void TDirectory::Append(TObject *obj)
{
   // Append object to current directory.

   if (obj == 0 || fList == 0) return;
   fList->Add(obj);
   if (!fMother) return;
   if (fMother->IsA() == TMapFile::Class()) {
      TMapFile *mfile = (TMapFile*)fMother;
      mfile->Add(obj);
   }
}<commit_msg>In TDirectory::Append, SetBit(kMustCleanup) for the object. This will force RecursiveRemove to be called when the object will be deleted. With this change, any TObject may be added to a TDirectory. When the object will be deleted, it will be automatically removed from any TDirectory referencing it.<commit_after>// @(#)root/base:$Name:  $:$Id: TDirectory.cxx,v 1.30 2002/08/04 21:55:57 rdm Exp $
// Author: <NAME>   28/11/94

/*************************************************************************
 * Copyright (C) 1995-2000, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "Strlen.h"
#include "TDirectory.h"
#include "TMapFile.h"
#include "TClassTable.h"
#include "TInterpreter.h"
#include "THashList.h"
#include "TBrowser.h"
#include "TFree.h"
#include "TKey.h"
#include "TROOT.h"
#include "TError.h"
#include "Bytes.h"
#include "TStreamerInfo.h"
#include "TRegexp.h"
#include "TProcessUUID.h"

TDirectory    *gDirectory;      //Pointer to current directory in memory

//______________________________________________________________________________
//Begin_Html
/*
<img src="gif/tdirectory_classtree.gif">
*/
//End_Html

ClassImp(TDirectory)

//______________________________________________________________________________
//
// A ROOT file is structured in Directories (like a file system).
// Each Directory has a list of Keys (see TKeys) and a list of objects
// in memory. A Key is a small object that describes the type and location
// of a persistent object in a file. The persistent object may be a directory.
//Begin_Html
/*
<img src="gif/fildir.gif">
*/
//End_Html
//
//      The structure of a file is shown in TFile::TFile
//

//______________________________________________________________________________
TDirectory::TDirectory() : TNamed()
{
//*-*-*-*-*-*-*-*-*-*-*-*Directory default constructor-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                    =============================
   fFile = 0;
   fList = 0;
   fKeys = 0;
   fWritable = kFALSE;
}

//______________________________________________________________________________
TDirectory::TDirectory(const char *name, const char *title, Option_t *classname)
           : TNamed(name, title)
{
//*-*-*-*-*-*-*-*-*-*-*-* Create a new Directory *-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                     ======================
//  A new directory with name,title is created in the current directory
//  The directory header information is immediatly saved on the file
//  A new key is added in the parent directory
//
//  When this constructor is called from a class directly derived
//  from TDirectory, the third argument classname MUST be specified.
//  In this case, classname must be the name of the derived class.
//
//  Note that the directory name cannot contain slashes.
//
   if (strchr(name,'/')) {
      ::Error("TDirectory::TDirectory","directory name cannot contain a slash", name);
      gDirectory = 0;
      return;
   }
   if (strlen(GetName()) == 0) {
      ::Error("TDirectory::TDirectory","directory name cannot be \"\"");
      gDirectory = 0;
      return;
   }

   Build();
   if (gDirectory == 0) return;
   if (gFile == 0) return;
   if (!gFile->IsWritable()) return; //*-* in case of a directory in memory
   if (gDirectory->GetKey(name)) {
      Error("TDirectory","Directory %s exists already",name);
      return;
   }
   TClass *cl = IsA();
   if (strlen(classname) != 0) cl = gROOT->GetClass(classname);
   if (!cl) {
      Error("TDirectory","Invalid class name: %s",classname);
      return;
   }
   fWritable    = kTRUE;
   fSeekParent  = gFile->GetSeekDir();
   Int_t nbytes = TDirectory::Sizeof();
   TKey *key    = new TKey(fName,fTitle,cl,nbytes);
   fNbytesName  = key->GetKeylen();
   fSeekDir     = key->GetSeekKey();
   if (fSeekDir == 0) return;
   char *buffer = key->GetBuffer();
   TDirectory::FillBuffer(buffer);
   Int_t cycle = gDirectory->AppendKey(key);
   key->WriteFile(cycle);
   fModified = kFALSE;
   gROOT->GetUUIDs()->AddUUID(fUUID,this);
}

//______________________________________________________________________________
TDirectory::TDirectory(const TDirectory &directory) : TNamed(directory)
{
   ((TDirectory&)directory).Copy(*this);
}

//______________________________________________________________________________
TDirectory::~TDirectory()
{
//*-*-*-*-*-*-*-*-*-*-*-*Directory destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                    ====================

   if (gROOT == 0) return; //when called by TROOT destructor

   TCollection::StartGarbageCollection();

   if (fList) {
      SetBit(kCloseDirectory);
      fList->Delete();
      SafeDelete(fList);
   }
   if (fKeys) {
      fKeys->Delete();
      SafeDelete(fKeys);
   }

   TCollection::EmptyGarbageCollection();

   if (gDebug)
      cerr << "TDirectory dtor called for "<< GetName() << endl;
}

//______________________________________________________________________________
void TDirectory::Append(TObject *obj)
{
   // Append object to current directory.

   if (obj == 0 || fList == 0) return;
   fList->Add(obj);
   obj->SetBit(kMustCleanup);
   if (!fMother) return;
   if (fMother->IsA() == TMapFile::Class()) {
      TMapFile *mfile = (TMapFile*)fMother;
      mfile->Add(obj);
   }
}
{'fraction_non_alphanumeric': 0.1839779005524862, 'fraction_numerical': 0.008103130755064457, 'mean_word_length': 3.16289766193944, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6114372', 'n_tokens_mistral': 3211, 'n_tokens_neox': 3062, 'n_words': 844}