Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TFile.cxx
Go to the documentation of this file.
1// @(#)root/io:$Id: 3a19890259ad6443ee313e090166614971ad4296 $
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
12/**
13\file TFile.cxx
14\class TFile
15\ingroup IO
16\brief A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-like logical structure, possibly including subdirectory hierarchies.
17\sa \ref IO
18\sa \ref rootio (or `io/doc/TFile` folder in your codebase)
19
20<summary>ROOT file data format specification</summary>
21
22A ROOT file is composed of a header, followed by consecutive data records
23(`TKey` instances) with a well defined format.
24
25The first data record starts at byte fBEGIN (currently set to kBEGIN).
26Bytes 1->kBEGIN contain the file description, when fVersion >= 1000000
27it is a large file (> 2 GB) and the offsets will be 8 bytes long and
28fUnits will be set to 8:
29
30Byte Range | Record Name | Description
31----------------|-------------|------------
321->4 | "root" | Root file identifier
335->8 | fVersion | File format version
349->12 | fBEGIN | Pointer to first data record
3513->16 [13->20] | fEND | Pointer to first free word at the EOF
3617->20 [21->28] | fSeekFree | Pointer to FREE data record
3721->24 [29->32] | fNbytesFree | Number of bytes in FREE data record
3825->28 [33->36] | nfree | Number of free data records
3929->32 [37->40] | fNbytesName | Number of bytes in TNamed at creation time
4033->33 [41->41] | fUnits | Number of bytes for file pointers
4134->37 [42->45] | fCompress | Compression level and algorithm
4238->41 [46->53] | fSeekInfo | Pointer to TStreamerInfo record
4342->45 [54->57] | fNbytesInfo | Number of bytes in TStreamerInfo record
4446->63 [58->75] | fUUID | Universal Unique ID
45
46For the purpose of magic bytes in the context of ROOT files' MIME definition,
47the following additional requirements are introduced:
48- The value of `fBEGIN` is fixed at 100.
49- The four bytes starting at position 96 are reserved and must be 0.
50If any changes to this need to be made, `media-types@iana.org` needs to be
51notified in accordance with RFC 6838.
52
53The key structure is as follows; if a key is located past the 32 bit file
54limit (> 2 GB) then some fields will be 8 instead of 4 bytes (see parts marked
55with square brackets below):
56
57Byte Range | Member Name | Description
58----------------|-----------|--------------
591->4 | Nbytes | Length of compressed object (in bytes)
605->6 | Version | TKey version identifier
617->10 | ObjLen | Length of uncompressed object
6211->14 | Datime | Date and time when object was written to file
6315->16 | KeyLen | Length of the key structure (in bytes)
6417->18 | Cycle | Cycle of key
6519->22 [19->26] | SeekKey | Pointer to record itself (consistency check)
6623->26 [27->34] | SeekPdir | Pointer to directory header
6727->27 [35->35] | lname | Number of bytes in the class name
6828->.. [36->..] | ClassName | Object Class Name
69..->.. | lname | Number of bytes in the object name
70..->.. | Name | lName bytes with the name of the object
71..->.. | lTitle | Number of bytes in the object title
72..->.. | Title | Title of the object
73-----> | DATA | Data bytes associated to the object
74
75Begin_Macro
76../../../tutorials/io/file.C
77End_Macro
78
79The structure of a directory is shown in TDirectoryFile::TDirectoryFile
80*/
81
82#include <ROOT/RConfig.hxx>
83
84#ifdef R__LINUX
85// for posix_fadvise
86#ifndef _XOPEN_SOURCE
87#define _XOPEN_SOURCE 600
88#endif
89#endif
90#include <fcntl.h>
91#include <errno.h>
92#include <sys/stat.h>
93#ifndef WIN32
94#include <unistd.h>
95#ifndef R__FBSD
96#include <sys/xattr.h>
97#endif
98#else
99# define ssize_t int
100# include <io.h>
101# include <sys/types.h>
102#endif
103
104#include "Bytes.h"
105#include "Compression.h"
106#include "RConfigure.h"
107#include "Strlen.h"
108#include "strlcpy.h"
109#include "snprintf.h"
110#include "TArrayC.h"
111#include "TBuffer.h"
112#include "TClass.h"
113#include "TClassEdit.h"
114#include "TClassTable.h"
115#include "TDatime.h"
116#include "TError.h"
117#include "TFile.h"
118#include "TFileCacheRead.h"
119#include "TFileCacheWrite.h"
120#include "TFree.h"
121#include "TInterpreter.h"
122#include "TKey.h"
123#include "TMakeProject.h"
124#include "TPluginManager.h"
125#include "TProcessUUID.h"
126#include "TRegexp.h"
127#include "TPRegexp.h"
128#include "TROOT.h"
129#include "TStreamerInfo.h"
130#include "TStreamerElement.h"
131#include "TSystem.h"
132#include "TTimeStamp.h"
133#include "TVirtualPerfStats.h"
134#include "TArchiveFile.h"
135#include "TEnv.h"
136#include "TVirtualMonitoring.h"
137#include "TVirtualMutex.h"
138#include "TMap.h"
139#include "TMathBase.h"
140#include "TObjString.h"
141#include "TStopwatch.h"
142#include "compiledata.h"
143#include <cmath>
144#include <iostream>
145#include <set>
146#include "TSchemaRule.h"
147#include "TSchemaRuleSet.h"
148#include "TThreadSlots.h"
149#include "TGlobal.h"
151#include <memory>
152
153#ifdef R__FBSD
154#include <sys/extattr.h>
155#endif
156
157using std::sqrt;
158
159std::atomic<Long64_t> TFile::fgBytesRead{0};
160std::atomic<Long64_t> TFile::fgBytesWrite{0};
161std::atomic<Long64_t> TFile::fgFileCounter{0};
162std::atomic<Int_t> TFile::fgReadCalls{0};
172
173#ifdef R__MACOSX
174/* On macOS getxattr takes two extra arguments that should be set to 0 */
175#define getxattr(path, name, value, size) getxattr(path, name, value, size, 0u, 0)
176#endif
177#ifdef R__FBSD
178#define getxattr(path, name, value, size) extattr_get_file(path, EXTATTR_NAMESPACE_USER, name, value, size)
179#endif
181const Int_t kBEGIN = 100;
182
184
185//*-*x17 macros/layout_file
186// Needed to add the "fake" global gFile to the list of globals.
187namespace {
188static struct AddPseudoGlobals {
189AddPseudoGlobals() {
190 // User "gCling" as synonym for "libCore static initialization has happened".
191 // This code here must not trigger it.
193}
194} gAddPseudoGlobals;
195}
196////////////////////////////////////////////////////////////////////////////////
197/// File default Constructor.
199TFile::TFile() : TDirectoryFile(), fCompress(ROOT::RCompressionSetting::EAlgorithm::kUseGlobal)
200{
201 fCacheReadMap = new TMap();
203
204 if (gDebug)
205 Info("TFile", "default ctor");
206}
207
208////////////////////////////////////////////////////////////////////////////////
209/// Opens or creates a local ROOT file.
210///
211/// \param[in] fname1 The name of the file
212/// \param[in] option Specifies the mode in which the file is opened
213/// \param[in] ftitle The title of the file
214/// \param[in] compress Specifies the compression algorithm and level
215///
216/// It is recommended to specify fname1 as "<file>.root". The suffix ".root"
217/// will be used by object browsers to automatically identify the file as
218/// a ROOT file. If the constructor fails in any way IsZombie() will
219/// return true. Use IsOpen() to check if the file is (still) open.
220/// To open non-local files use the static TFile::Open() method, that
221/// will take care of opening the files using the correct remote file
222/// access plugin.
223///
224/// Option | Description
225/// -------|------------
226/// NEW or CREATE | Create a new file and open it for writing, if the file already exists the file is not opened.
227/// RECREATE | Create a new file, if the file already exists it will be overwritten.
228/// UPDATE | Open an existing file for writing. If no file exists, it is created.
229/// READ | Open an existing file for reading (default).
230/// NET | Used by derived remote file access classes, not a user callable option.
231/// WEB | Used by derived remote http access class, not a user callable option.
232/// READ_WITHOUT_GLOBALREGISTRATION | Used by TTreeProcessorMT, not a user callable option.
233///
234/// If option = "" (default), READ is assumed.
235/// The file can be specified as a URL of the form:
236///
237/// file:///user/rdm/bla.root or file:/user/rdm/bla.root
238///
239/// The file can also be a member of an archive, in which case it is
240/// specified as:
241///
242/// multi.zip#file.root or multi.zip#0
243///
244/// which will open file.root which is a member of the file multi.zip
245/// archive or member 1 from the archive. For more on archive file
246/// support see the TArchiveFile class.
247/// TFile and its remote access plugins can also be used to open any
248/// file, i.e. also non ROOT files, using:
249///
250/// file.tar?filetype=raw
251///
252/// This is convenient because the many remote file access plugins allow
253/// easy access to/from the many different mass storage systems.
254/// The title of the file (ftitle) will be shown by the ROOT browsers.
255/// A ROOT file (like a Unix file system) may contain objects and
256/// directories. There are no restrictions for the number of levels
257/// of directories.
258/// A ROOT file is designed such that one can write in the file in pure
259/// sequential mode (case of BATCH jobs). In this case, the file may be
260/// read sequentially again without using the file index written
261/// at the end of the file. In case of a job crash, all the information
262/// on the file is therefore protected.
263/// A ROOT file can be used interactively. In this case, one has the
264/// possibility to delete existing objects and add new ones.
265/// When an object is deleted from the file, the freed space is added
266/// into the FREE linked list (fFree). The FREE list consists of a chain
267/// of consecutive free segments on the file. At the same time, the first
268/// 4 bytes of the freed record on the file are overwritten by GAPSIZE
269/// where GAPSIZE = -(Number of bytes occupied by the record).
270/// Option compress is used to specify the compression level and algorithm:
271///
272/// compress = 100 * algorithm + level
273///
274/// Level | Explanation
275/// ------|-------------
276/// 0 | objects written to this file will not be compressed.
277/// 1 | minimal compression level but fast.
278/// ... | ....
279/// 9 | maximal compression level but slower and might use more memory.
280/// (For the currently supported algorithms, the maximum level is 9)
281/// If compress is negative it indicates the compression level is not set yet.
282/// The enumeration ROOT::RCompressionSetting::EAlgorithm associates each
283/// algorithm with a number. There is a utility function to help
284/// to set the value of compress. For example,
285/// ROOT::CompressionSettings(ROOT::kLZMA, 1)
286/// will build an integer which will set the compression to use
287/// the LZMA algorithm and compression level 1. These are defined
288/// in the header file <em>Compression.h</em>.
289/// Note that the compression settings may be changed at any time.
290/// The new compression settings will only apply to branches created
291/// or attached after the setting is changed and other objects written
292/// after the setting is changed.
293/// In case the file does not exist or is not a valid ROOT file,
294/// it is made a Zombie. One can detect this situation with a code like:
295/// ~~~{.cpp}
296/// TFile f("file.root");
297/// if (f.IsZombie()) {
298/// std::cout << "Error opening file" << std::endl;
299/// exit(-1);
300/// }
301/// ~~~
302/// If you open a file instead with TFile::Open("file.root") use rather
303/// the following code as a nullptr is returned.
304/// ~~~{.cpp}
305/// TFile* f = TFile::Open("file.root");
306/// if (!f) {
307/// std::cout << "Error opening file" << std::endl;
308/// exit(-1);
309/// }
310/// ~~~
311/// When opening the file, the system checks the validity of this directory.
312/// If something wrong is detected, an automatic Recovery is performed. In
313/// this case, the file is scanned sequentially reading all logical blocks
314/// and attempting to rebuild a correct directory (see TFile::Recover).
315/// One can disable the automatic recovery procedure when reading one
316/// or more files by setting the environment variable "TFile.Recover: 0"
317/// in the system.rootrc file.
318///
319/// A bit `TFile::kReproducible` can be enabled specifying
320/// the `"reproducible"` url option when creating the file:
321/// ~~~{.cpp}
322/// TFile *f = TFile::Open("name.root?reproducible","RECREATE","File title");
323/// ~~~
324/// Unlike regular `TFile`s, the content of such file has reproducible binary
325/// content when writing exactly same data. This achieved by writing pre-defined
326/// values for creation and modification date of TKey/TDirectory objects and
327/// null value for TUUID objects inside TFile. As drawback, TRef objects stored
328/// in such file cannot be read correctly.
329///
330/// In case the name of the file is not reproducible either (in case of
331/// creating temporary filenames) a value can be passed to the reproducible
332/// option to replace the name stored in the file.
333/// ~~~{.cpp}
334/// TFile *f = TFile::Open("tmpname.root?reproducible=fixedname","RECREATE","File title");
335/// ~~~
337TFile::TFile(const char *fname1, Option_t *option, const char *ftitle, Int_t compress)
338 : TDirectoryFile(), fCompress(compress), fUrl(fname1,kTRUE)
339{
340 if (!gROOT)
341 ::Fatal("TFile::TFile", "ROOT system not initialized");
342
343 auto zombify = [this] {
344 // error in file opening occurred, make this object a zombie
347 gROOT->GetListOfClosedObjects()->Add(this);
348 }
349 MakeZombie();
351 };
352
353 fOption = option;
354 if (strlen(fUrl.GetProtocol()) != 0 && strcmp(fUrl.GetProtocol(), "file") != 0 && !fOption.BeginsWith("NET") &&
355 !fOption.BeginsWith("WEB")) {
356 Error("TFile",
357 "please use TFile::Open to access remote files:\n\tauto f = std::unique_ptr<TFile>{TFile::Open(\"%s\")};",
358 fname1);
359 zombify();
360 return;
361 }
362
363 // store name without the options as name and title
364 TString sfname1 = fname1;
365 if (sfname1.Index("?") != kNPOS) {
366 TString s = sfname1(0, sfname1.Index("?"));
367 SetName(s);
369 } else
370 SetName(fname1);
371
372 SetTitle(ftitle);
373
374 // accept also URL like "file:..." syntax
375 fname1 = fUrl.GetFile();
376
377 // if option contains filetype=raw then go into raw file mode
378 if (strstr(fUrl.GetOptions(), "filetype=raw"))
380
381 // if option contains filetype=pcm then go into ROOT PCM file mode
382 if (strstr(fUrl.GetOptions(), "filetype=pcm"))
384
385 if (fUrl.HasOption("reproducible"))
387
388 // We are opening synchronously
390
391 BuildDirectoryFile(this, nullptr);
392
393 fVersion = gROOT->GetVersionInt(); //ROOT version in integer format
394 fUnits = 4;
395 fCacheReadMap = new TMap();
397
399
400 if (fIsRootFile && !fIsPcmFile && fOption != "NEW" && fOption != "CREATE"
401 && fOption != "RECREATE") {
402 // If !gPluginMgr then we are at startup and cannot handle plugins
403 // as TArchiveFile yet.
404 fArchive = gPluginMgr ? TArchiveFile::Open(fUrl.GetUrl(), this) : nullptr;
405 if (fArchive) {
406 fname1 = fArchive->GetArchiveName();
407 // if no archive member is specified then this TFile is just used
408 // to read the archive contents
409 if (!strlen(fArchive->GetMemberName()))
411 }
412 }
413
414 if (fOption.Contains("_WITHOUT_GLOBALREGISTRATION")) {
415 fOption = fOption.ReplaceAll("_WITHOUT_GLOBALREGISTRATION", "");
416 fGlobalRegistration = false;
417 if (fList) {
418 fList->UseRWLock(false);
419 }
420 }
421
422 if (fOption == "NET")
423 return;
424
425 if (fOption == "WEB") {
426 fOption = "READ";
428 return;
429 }
430
431 if (fOption == "NEW")
432 fOption = "CREATE";
433
434 Bool_t create = (fOption == "CREATE") ? kTRUE : kFALSE;
435 Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
436 Bool_t update = (fOption == "UPDATE") ? kTRUE : kFALSE;
437 Bool_t read = (fOption == "READ") ? kTRUE : kFALSE;
438 if (!create && !recreate && !update && !read) {
439 read = kTRUE;
440 fOption = "READ";
441 }
442
443 Bool_t devnull = kFALSE;
444
445 if (!fname1 || !fname1[0]) {
446 Error("TFile", "file name is not specified");
447 zombify();
448 return;
449 }
450
451 // support dumping to /dev/null on UNIX
452 if (!strcmp(fname1, "/dev/null") &&
454 devnull = kTRUE;
455 create = kTRUE;
456 recreate = kFALSE;
457 update = kFALSE;
458 read = kFALSE;
459 fOption = "CREATE";
461 }
462
463 TString fname(fname1);
464 if (!gSystem->ExpandPathName(fname)) {
465 SetName(fname.Data());
466 fRealName = GetName();
469 }
470 fname = fRealName.Data();
471 } else {
472 Error("TFile", "error expanding path %s", fname1);
473 zombify();
474 return;
475 }
476
477 // If the user supplied a value to the option take it as the name to set for
478 // the file instead of the actual filename
479 if (TestBit(kReproducible)) {
480 if(auto name=fUrl.GetValueFromOptions("reproducible")) {
481 SetName(name);
482 }
483 }
484
485 if (recreate) {
486 if (!gSystem->AccessPathName(fname.Data(), kFileExists)) {
487 if (gSystem->Unlink(fname.Data()) != 0) {
488 SysError("TFile", "could not delete %s (errno: %d)",
489 fname.Data(), gSystem->GetErrno());
490 zombify();
491 return;
492 }
493 }
494 recreate = kFALSE;
495 create = kTRUE;
496 fOption = "CREATE";
497 }
498 if (create && !devnull && !gSystem->AccessPathName(fname.Data(), kFileExists)) {
499 Error("TFile", "file %s already exists", fname.Data());
500 zombify();
501 return;
502 }
503 if (update) {
504 if (gSystem->AccessPathName(fname.Data(), kFileExists)) {
505 update = kFALSE;
506 create = kTRUE;
507 }
509 Error("TFile", "no write permission, could not open file %s", fname.Data());
510 zombify();
511 return;
512 }
513 }
514 if (read) {
515 if (gSystem->AccessPathName(fname.Data(), kFileExists)) {
516 Error("TFile", "file %s does not exist", fname.Data());
517 zombify();
518 return;
519 }
521 Error("TFile", "no read permission, could not open file %s", fname.Data());
522 zombify();
523 return;
524 }
525 }
526
527 // Connect to file system stream
528 if (create || update) {
529#ifndef WIN32
530 fD = TFile::SysOpen(fname.Data(), O_RDWR | O_CREAT, 0644);
531#else
532 fD = TFile::SysOpen(fname.Data(), O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
533#endif
534 if (fD == -1) {
535 SysError("TFile", "file %s can not be opened", fname.Data());
536 zombify();
537 return;
538 }
540 } else {
541#ifndef WIN32
542 fD = TFile::SysOpen(fname.Data(), O_RDONLY, 0644);
543#else
544 fD = TFile::SysOpen(fname.Data(), O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
545#endif
546 if (fD == -1) {
547 SysError("TFile", "file %s can not be opened for reading", fname.Data());
548 zombify();
549 return;
550 }
552 }
553
554 // calling virtual methods from constructor not a good idea, but it is how code was developed
555 TFile::Init(create); // NOLINT: silence clang-tidy warnings
556}
557
558////////////////////////////////////////////////////////////////////////////////
559/// File destructor.
562{
563 Close(); // NOLINT: silence clang-tidy warnings
564
565 // In case where the TFile is still open at 'tear-down' time the order of operation will be
566 // call Close("nodelete")
567 // then later call delete TFile
568 // which means that at this point we might still have object held and those
569 // might requires a 'valid' TFile object in their desctructor (for example,
570 // TTree call's GetReadCache which expects a non-null fCacheReadMap).
571 // So delete the objects (if any) now.
572
573 if (fList)
574 fList->Delete("slow");
575
585
588 gROOT->GetListOfClosedObjects()->Remove(this);
589 gROOT->GetUUIDs()->RemoveUUID(GetUniqueID());
590 }
591
592 if (IsOnHeap()) {
593 // Delete object from CINT symbol table so it can not be used anymore.
594 // CINT object are always on the heap.
595 gInterpreter->ResetGlobalVar(this);
596 }
597
598 if (gDebug)
599 Info("~TFile", "dtor called for %s [%zx]", GetName(),(size_t)this);
600}
601
602////////////////////////////////////////////////////////////////////////////////
603/// Initialize a TFile object.
604///
605/// \param[in] create Create a new file.
606///
607/// TFile implementations providing asynchronous open functionality need to
608/// override this method to run the appropriate checks before calling this
609/// standard initialization part. See TNetXNGFile::Init for an example.
611void TFile::Init(Bool_t create)
612{
613 if (fInitDone)
614 // Already called once
615 return;
617
618 if (!fIsRootFile) {
620 return;
621 }
622
623 if (fArchive) {
624 if (fOption != "READ") {
625 Error("Init", "archive %s can only be opened in read mode", GetName());
626 delete fArchive;
627 fArchive = nullptr;
629 goto zombie;
630 }
631
633
634 if (fIsArchive) return;
635
636 // Make sure the anchor is in the name
637 if (!fNoAnchorInName)
638 if (!strchr(GetName(),'#'))
640
641 if (fArchive->SetCurrentMember() != -1)
643 else {
644 Error("Init", "member %s not found in archive %s",
646 delete fArchive;
647 fArchive = nullptr;
649 goto zombie;
650 }
651 }
652
653 Int_t nfree;
654 fBEGIN = (Long64_t)kBEGIN; //First used word in file following the file header
655
656 // make newly opened file the current file and directory
657 cd();
658
659 if (create) {
660 //*-*---------------NEW file
661 fFree = new TList;
662 fEND = fBEGIN; //Pointer to end of file
663 new TFree(fFree, fBEGIN, Long64_t(kStartBigFile)); //Create new free list
664
665 //*-* Write Directory info
666 Int_t namelen= TNamed::Sizeof();
667 Int_t nbytes = namelen + TDirectoryFile::Sizeof();
668 TKey *key = new TKey(fName, fTitle, IsA(), nbytes, this);
669 fNbytesName = key->GetKeylen() + namelen;
670 fSeekDir = key->GetSeekKey();
671 fSeekFree = 0;
672 fNbytesFree = 0;
673 WriteHeader();
674 char *buffer = key->GetBuffer();
675 TNamed::FillBuffer(buffer);
677 key->WriteFile();
678 delete key;
679 } else {
680 //*-*----------------UPDATE
681 //char *header = new char[kBEGIN];
682 char *header = new char[kBEGIN+200];
683 Seek(0); // NOLINT: silence clang-tidy warnings
684 //ReadBuffer(header, kBEGIN);
685 if (ReadBuffer(header, kBEGIN+200)) { // NOLINT: silence clang-tidy warnings
686 // ReadBuffer returns kTRUE in case of failure.
687 Error("Init","%s failed to read the file type data.",
688 GetName());
689 delete [] header;
690 goto zombie;
691 }
692
693 // make sure this is a ROOT file
694 if (strncmp(header, "root", 4)) {
695 Error("Init", "%s not a ROOT file", GetName());
696 delete [] header;
697 goto zombie;
698 }
699
700 char *buffer = header + 4; // skip the "root" file identifier
701 frombuf(buffer, &fVersion);
702 Int_t headerLength;
703 frombuf(buffer, &headerLength);
704 fBEGIN = (Long64_t)headerLength;
705 if (fVersion < 1000000) { //small file
706 Int_t send,sfree,sinfo;
707 frombuf(buffer, &send); fEND = (Long64_t)send;
708 frombuf(buffer, &sfree); fSeekFree= (Long64_t)sfree;
709 frombuf(buffer, &fNbytesFree);
710 frombuf(buffer, &nfree);
711 frombuf(buffer, &fNbytesName);
712 frombuf(buffer, &fUnits );
713 frombuf(buffer, &fCompress);
714 frombuf(buffer, &sinfo); fSeekInfo = (Long64_t)sinfo;
715 frombuf(buffer, &fNbytesInfo);
716 } else { // new format to support large files
717 frombuf(buffer, &fEND);
718 frombuf(buffer, &fSeekFree);
719 frombuf(buffer, &fNbytesFree);
720 frombuf(buffer, &nfree);
721 frombuf(buffer, &fNbytesName);
722 frombuf(buffer, &fUnits );
723 frombuf(buffer, &fCompress);
724 frombuf(buffer, &fSeekInfo);
725 frombuf(buffer, &fNbytesInfo);
726 }
727 if (fBEGIN < 0 || fBEGIN > fEND) {
728 // humm fBEGIN is wrong ....
729 Error("Init","file %s has an incorrect header length (%lld) or incorrect end of file length (%lld)",
731 delete [] header;
732 goto zombie;
733 }
735 //*-*-------------Read Free segments structure if file is writable
736 if (fWritable) {
737 fFree = new TList;
738 if (fSeekFree > fBEGIN) {
739 ReadFree(); // NOLINT: silence clang-tidy warnings
740 } else {
741 Warning("Init","file %s probably not closed, cannot read free segments",GetName());
742 }
743 }
744 //*-*-------------Read directory info
745 // buffer_keyloc is the start of the key record.
746 char *buffer_keyloc = nullptr;
747
749 if ( (nbytes + fBEGIN) > fEND) {
750 // humm fBEGIN is wrong ....
751 Error("Init","file %s has an incorrect header length (%lld) or incorrect end of file length (%lld)",
752 GetName(),fBEGIN+nbytes,fEND);
753 delete [] header;
754 goto zombie;
755 }
756 if (nbytes+fBEGIN > kBEGIN+200) {
757 delete [] header;
758 header = new char[nbytes];
759 buffer = header;
760 Seek(fBEGIN); // NOLINT: silence clang-tidy warnings
761 if (ReadBuffer(buffer,nbytes)) { // NOLINT: silence clang-tidy warnings
762 // ReadBuffer returns kTRUE in case of failure.
763 Error("Init","%s failed to read the file header information at %lld (size=%d)",
764 GetName(),fBEGIN,nbytes);
765 delete [] header;
766 goto zombie;
767 }
768 buffer = header+fNbytesName;
769 buffer_keyloc = header;
770 } else {
771 buffer = header+fBEGIN+fNbytesName;
772 buffer_keyloc = header+fBEGIN;
773 }
774 Version_t version,versiondir;
775 frombuf(buffer,&version); versiondir = version%1000;
776 fDatimeC.ReadBuffer(buffer);
777 fDatimeM.ReadBuffer(buffer);
778 frombuf(buffer, &fNbytesKeys);
779 frombuf(buffer, &fNbytesName);
780 if (version > 1000) {
781 frombuf(buffer, &fSeekDir);
782 frombuf(buffer, &fSeekParent);
783 frombuf(buffer, &fSeekKeys);
784 } else {
785 Int_t sdir,sparent,skeys;
786 frombuf(buffer, &sdir); fSeekDir = (Long64_t)sdir;
787 frombuf(buffer, &sparent); fSeekParent = (Long64_t)sparent;
788 frombuf(buffer, &skeys); fSeekKeys = (Long64_t)skeys;
789 }
790 if (versiondir > 1) fUUID.ReadBuffer(buffer);
791
792 //*-*---------read TKey::FillBuffer info
793 buffer_keyloc += sizeof(Int_t); // Skip NBytes;
794 Version_t keyversion;
795 frombuf(buffer_keyloc, &keyversion);
796 // Skip ObjLen, DateTime, KeyLen, Cycle, SeekKey, SeekPdir
797 if (keyversion > 1000) {
798 // Large files
799 buffer_keyloc += 2*sizeof(Int_t)+2*sizeof(Short_t)+2*sizeof(Long64_t);
800 } else {
801 buffer_keyloc += 2*sizeof(Int_t)+2*sizeof(Short_t)+2*sizeof(Int_t);
802 }
804 cname.ReadBuffer(buffer_keyloc);
805 cname.ReadBuffer(buffer_keyloc); // fName.ReadBuffer(buffer); file may have been renamed
806 fTitle.ReadBuffer(buffer_keyloc);
807 delete [] header;
808 if (fNbytesName < 10 || fNbytesName > 10000) {
809 Error("Init","cannot read directory info of file %s", GetName());
810 goto zombie;
811 }
812
813 //*-* -------------Check if file is truncated
815 if ((size = GetSize()) == -1) { // NOLINT: silence clang-tidy warnings
816 Error("Init", "cannot stat the file %s", GetName());
817 goto zombie;
818 }
819
820 //*-* -------------Check if, in case of inconsistencies, we are requested to
821 //*-* -------------attempt recovering the file
822 Bool_t tryrecover = (gEnv->GetValue("TFile.Recover", 1) == 1) ? kTRUE : kFALSE;
823
824 //*-* -------------Check if we need to enable forward compatible with version
825 //*-* -------------prior to v6.30
826 if (gEnv->GetValue("TFile.v630forwardCompatibility", 0) == 1)
828
829 //*-* -------------Read keys of the top directory
830 if (fSeekKeys > fBEGIN && fEND <= size) {
831 //normal case. Recover only if file has no keys
833 gDirectory = this;
834 if (!GetNkeys()) {
835 if (tryrecover) {
836 Recover(); // NOLINT: silence clang-tidy warnings
837 } else {
838 Error("Init", "file %s has no keys", GetName());
839 goto zombie;
840 }
841 }
842 } else if ((fBEGIN+nbytes == fEND) && (fEND == size)) {
843 //the file might be open by another process and nothing written to the file yet
844 Warning("Init","file %s has no keys", GetName());
845 gDirectory = this;
846 } else {
847 //something had been written to the file. Trailer is missing, must recover
848 if (fEND > size) {
849 if (tryrecover) {
850 Error("Init","file %s is truncated at %lld bytes: should be %lld, "
851 "trying to recover", GetName(), size, fEND);
852 } else {
853 Error("Init","file %s is truncated at %lld bytes: should be %lld",
854 GetName(), size, fEND);
855 goto zombie;
856 }
857 } else {
858 if (tryrecover) {
859 Warning("Init","file %s probably not closed, "
860 "trying to recover", GetName());
861 } else {
862 Warning("Init","file %s probably not closed", GetName());
863 goto zombie;
864 }
865 }
866 Int_t nrecov = Recover(); // NOLINT: silence clang-tidy warnings
867 if (nrecov) {
868 Warning("Init", "successfully recovered %d keys", nrecov);
869 } else {
870 Warning("Init", "no keys recovered, file has been made a Zombie");
871 goto zombie;
872 }
873 }
874 }
875
878 gROOT->GetListOfFiles()->Add(this);
879 gROOT->GetUUIDs()->AddUUID(fUUID, this);
880 }
881
882 // Create StreamerInfo index
883 {
884 Int_t lenIndex = gROOT->GetListOfStreamerInfo()->GetSize()+1;
885 if (lenIndex < 5000) lenIndex = 5000;
886 fClassIndex = new TArrayC(lenIndex);
887 if (fgReadInfo) {
888 if (fSeekInfo > fBEGIN) {
889 ReadStreamerInfo(); // NOLINT: silence clang-tidy warnings
890 if (IsZombie()) {
892 gROOT->GetListOfFiles()->Remove(this);
893 goto zombie;
894 }
895 } else if (fVersion != gROOT->GetVersionInt() && fVersion > 30000) {
896 // Don't complain about missing streamer info for empty files.
897 if (fKeys->GetSize()) {
898 // #14068: we take into account the different way of expressing the version
899 const auto separator = fVersion < 63200 ? "/" : ".";
900 const auto thisVersion = gROOT->GetVersionInt();
901 const auto msg = "no StreamerInfo found in %s therefore preventing schema evolution when reading this file. "
902 "The file was produced with ROOT version %d.%02d%s%02d, "
903 "while the current version is %d.%02d.%02d";
904 Warning("Init", msg,
905 GetName(),
906 fVersion / 10000, (fVersion / 100) % (100), separator, fVersion % 100,
907 thisVersion / 10000, (thisVersion / 100) % (100), thisVersion % 100);
908 }
909 }
910 }
911 }
912
913 // Count number of TProcessIDs in this file
914 {
915 TIter next(fKeys);
916 TKey *key;
917 while ((key = (TKey*)next())) {
918 if (!strcmp(key->GetClassName(),"TProcessID")) fNProcessIDs++;
919 }
921 }
922
923 return;
924
925zombie:
928 gROOT->GetListOfClosedObjects()->Add(this);
929 }
930 // error in file opening occurred, make this object a zombie
932 MakeZombie();
934}
935
936////////////////////////////////////////////////////////////////////////////////
937/// Close a file.
938///
939/// \param[in] option If option == "R", all TProcessIDs referenced by this file are deleted.
940///
941/// Calling TFile::Close("R") might be necessary in case one reads a long list
942/// of files having TRef, writing some of the referenced objects or TRef
943/// to a new file. If the TRef or referenced objects of the file being closed
944/// will not be referenced again, it is possible to minimize the size
945/// of the TProcessID data structures in memory by forcing a delete of
946/// the unused TProcessID.
949{
950 TString opt = option;
951
952 opt.ToLower();
953
954 if (!IsOpen()) return;
955
956 if (fIsArchive || !fIsRootFile) {
958 SysClose(fD);
959 fD = -1;
960
963
964 return;
965 }
966
967 if (IsWritable()) {
969 }
970
971 // Finish any concurrent I/O operations before we close the file handles.
973 {
974 TIter iter(fCacheReadMap);
975 TObject *key = nullptr;
976 while ((key = iter()) != nullptr) {
977 TFileCacheRead *cache = dynamic_cast<TFileCacheRead *>(fCacheReadMap->GetValue(key));
978 cache->Close();
979 }
980 }
981
982 // Delete all supported directories structures from memory
983 // If gDirectory points to this object or any of the nested
984 // TDirectoryFile, TDirectoryFile::Close will induce the proper cd.
985 fMustFlush = kFALSE; // Make sure there is only one Flush.
987
988 if (IsWritable()) {
989 TFree *f1 = (TFree*)fFree->First();
990 if (f1) {
991 WriteFree(); //*-*- Write free segments linked list
992 WriteHeader(); //*-*- Now write file header ; this forces a Flush/fsync
993 } else {
994 Flush();
995 }
996 }
998
1000
1003
1004 delete fClassIndex;
1005 fClassIndex = nullptr;
1006
1007 // Delete free segments from free list (but don't delete list header)
1008 if (fFree) {
1009 fFree->Delete();
1010 }
1011
1012 if (IsOpen()) {
1013 SysClose(fD);
1014 fD = -1;
1015 }
1016
1017 fWritable = kFALSE;
1018
1019 // delete the TProcessIDs
1020 TList pidDeleted;
1021 TIter next(fProcessIDs);
1022 TProcessID *pid;
1023 while ((pid = (TProcessID*)next())) {
1024 if (!pid->DecrementCount()) {
1025 if (pid != TProcessID::GetSessionProcessID()) pidDeleted.Add(pid);
1026 } else if(opt.Contains("r")) {
1027 pid->Clear();
1028 }
1029 }
1030 pidDeleted.Delete();
1031
1032 if (!IsZombie() && fGlobalRegistration) {
1034 gROOT->GetListOfFiles()->Remove(this);
1035 gROOT->GetListOfBrowsers()->RecursiveRemove(this);
1036 gROOT->GetListOfClosedObjects()->Add(this);
1037 } else {
1038 // If we are a zombie, we are already in the list of closed objects.
1039 }
1040}
1041
1042////////////////////////////////////////////////////////////////////////////////
1043/// Creates key for object and converts data to buffer.
1045TKey* TFile::CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t bufsize)
1046{
1047 return new TKey(obj, name, bufsize, mother);
1048}
1049
1050////////////////////////////////////////////////////////////////////////////////
1051/// Creates key for object and converts data to buffer.
1053TKey* TFile::CreateKey(TDirectory* mother, const void* obj, const TClass* cl, const char* name, Int_t bufsize)
1054{
1055 return new TKey(obj, cl, name, bufsize, mother);
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Return the current ROOT file if any.
1060///
1061/// Note that if 'cd' has been called on a TDirectory that does not belong to a file,
1062/// gFile will be unchanged and still points to the file of the previous current
1063/// directory that was a file.
1066{
1067 static TFile *currentFile = nullptr;
1068 if (!gThreadTsd)
1069 return currentFile;
1070 else
1071 return *(TFile**)(*gThreadTsd)(&currentFile,ROOT::kFileThreadSlot);
1072}
1073
1074////////////////////////////////////////////////////////////////////////////////
1075/// Delete object namecycle.
1076///
1077/// \param[in] namecycle Encodes the name and cycle of the objects to delete
1078///
1079/// Namecycle identifies an object in the top directory of the file namecycle
1080/// has the format <em>name;cycle</em>.
1081/// - <em>name = *</em> means all objects
1082/// - <em>cycle = *</em> means all cycles (memory and keys)
1083/// - <em>cycle = ""</em> or cycle = 9999 ==> apply to a memory object
1084/// When name=* use T* to delete subdirectories also
1085///
1086/// Examples:
1087/// name/cycle | Action
1088/// -----------|-------
1089/// foo | delete object named foo in memory
1090/// foo;1 | delete cycle 1 of foo on file
1091/// foo;* | delete all cycles of foo on disk and also from memory
1092/// *;2 | delete all objects on file having the cycle 2
1093/// *;* | delete all objects from memory and file
1094/// T*;* | delete all objects from memory and file and all subdirectories
1096void TFile::Delete(const char *namecycle)
1097{
1098 if (gDebug)
1099 Info("Delete", "deleting name = %s", namecycle);
1100
1101 TDirectoryFile::Delete(namecycle);
1102}
1103
1104////////////////////////////////////////////////////////////////////////////////
1105/// Fill Graphics Structure and Paint.
1106///
1107/// Loop on all objects (memory or file) and all subdirectories.
1110{
1111 GetList()->R__FOR_EACH(TObject,Draw)(option);
1112}
1113
1114////////////////////////////////////////////////////////////////////////////////
1115/// Draw map of objects in this file. The map drawing is handled by TFileDrawMap.
1116/// Once the map is drawn, turn on the TCanvas option "View->Event Statusbar". Then, when
1117/// moving the mouse in the canvas, the "Event Status" panels shows the object corresponding
1118/// to the mouse position.
1119///
1120/// Example:
1121/// ~~~{.cpp}
1122/// auto f = new TFile("myfile.root");
1123/// f->DrawMap();
1124/// ~~~
1126void TFile::DrawMap(const char *keys, Option_t *option)
1127{
1129 if ((h = gROOT->GetPluginManager()->FindHandler("TFileDrawMap"))) {
1130 if (h->LoadPlugin() == -1)
1131 return;
1132 h->ExecPlugin(3, this, keys, option);
1133 }
1134}
1135
1136////////////////////////////////////////////////////////////////////////////////
1137/// Synchronize a file's in-memory and on-disk states.
1139void TFile::Flush()
1140{
1141 if (IsOpen() && fWritable) {
1143 if (SysSync(fD) < 0) {
1144 // Write the system error only once for this file
1146 SysError("Flush", "error flushing file %s", GetName());
1147 }
1148 }
1149}
1150
1151////////////////////////////////////////////////////////////////////////////////
1152/// Flush the write cache if active.
1153///
1154/// Return kTRUE in case of error
1157{
1158 if (fCacheWrite && IsOpen() && fWritable)
1159 return fCacheWrite->Flush();
1160 return kFALSE;
1161}
1162
1163////////////////////////////////////////////////////////////////////////////////
1164/// Encode file output buffer.
1165///
1166/// The file output buffer contains only the FREE data record.
1168void TFile::FillBuffer(char *&buffer)
1169{
1170 Version_t version = TFile::Class_Version();
1171 tobuf(buffer, version);
1172}
1173
1174////////////////////////////////////////////////////////////////////////////////
1175/// Return the best buffer size of objects on this file.
1176///
1177/// The best buffer size is estimated based on the current mean value
1178/// and standard deviation of all objects written so far to this file.
1179/// Returns mean value + one standard deviation.
1182{
1183 if (!fWritten) return TBuffer::kInitialSize;
1185 Double_t rms2 = TMath::Abs(fSum2Buffer/fSumBuffer -mean*mean);
1186 Double_t result = mean + sqrt(rms2);
1187 if (result >= (double)std::numeric_limits<Int_t>::max()) {
1188 return std::numeric_limits<Int_t>::max() -1;
1189 } else {
1190 return (Int_t)result;
1191 }
1192}
1193
1194////////////////////////////////////////////////////////////////////////////////
1195/// Return the file compression factor.
1196///
1197/// Add total number of compressed/uncompressed bytes for each key.
1198/// Returns the ratio of the two.
1201{
1202 Short_t keylen;
1203 UInt_t datime;
1204 Int_t nbytes, objlen, nwh = 64;
1205 char *header = new char[fBEGIN];
1206 char *buffer;
1207 Long64_t idcur = fBEGIN;
1208 Float_t comp,uncomp;
1209 comp = uncomp = fBEGIN;
1210
1211 while (idcur < fEND-100) {
1212 Seek(idcur);
1213 if (ReadBuffer(header, nwh)) {
1214 // ReadBuffer returns kTRUE in case of failure.
1215// Error("GetCompressionFactor","%s failed to read the key header information at %lld (size=%d).",
1216// GetName(),idcur,nwh);
1217 break;
1218 }
1219 buffer=header;
1220 frombuf(buffer, &nbytes);
1221 if (nbytes < 0) {
1222 idcur -= nbytes;
1223 Seek(idcur);
1224 continue;
1225 }
1226 if (nbytes == 0) break; //this may happen when the file is corrupted
1227 Version_t versionkey;
1228 frombuf(buffer, &versionkey);
1229 frombuf(buffer, &objlen);
1230 frombuf(buffer, &datime);
1231 frombuf(buffer, &keylen);
1232 if (!objlen) objlen = nbytes-keylen;
1233 comp += nbytes;
1234 uncomp += keylen + objlen;
1235 idcur += nbytes;
1236 }
1237 delete [] header;
1238 return uncomp/comp;
1239}
1240
1241////////////////////////////////////////////////////////////////////////////////
1242/// Method returning errno.
1244Int_t TFile::GetErrno() const
1245{
1246 return TSystem::GetErrno();
1247}
1248
1249////////////////////////////////////////////////////////////////////////////////
1250/// Method resetting the errno.
1252void TFile::ResetErrno() const
1253{
1255}
1256
1257////////////////////////////////////////////////////////////////////////////////
1258/// Return a pointer to the current read cache.
1260TFileCacheRead *TFile::GetCacheRead(const TObject* tree) const
1261{
1262 if (!tree) {
1263 if (!fCacheRead && fCacheReadMap->GetSize() == 1) {
1264 TIter next(fCacheReadMap);
1265 return (TFileCacheRead *)fCacheReadMap->GetValue(next());
1266 }
1267 return fCacheRead;
1268 }
1270 if (!cache) return fCacheRead;
1271 return cache;
1272}
1273
1274////////////////////////////////////////////////////////////////////////////////
1275/// Return a pointer to the current write cache.
1278{
1279 return fCacheWrite;
1280}
1281
1282////////////////////////////////////////////////////////////////////////////////
1283/// Read the logical record header starting at a certain postion.
1284///
1285/// \param[in] buf pointer to buffer
1286/// \param[in] first read offset
1287/// \param[in] maxbytes Bytes which are read into buf.
1288/// \param[out] nbytes Number of bytes in record if negative, this is a deleted
1289/// record if 0, cannot read record, wrong value of argument first
1290/// \param[out] objlen Uncompressed object size
1291/// \param[out] keylen Length of logical record header
1292///
1293/// The function reads nread bytes
1294/// where nread is the minimum of maxbytes and the number of bytes
1295/// before the end of file. The function returns nread.
1296/// Note that the arguments objlen and keylen are returned only
1297/// if maxbytes >=16
1299Int_t TFile::GetRecordHeader(char *buf, Long64_t first, Int_t maxbytes, Int_t &nbytes, Int_t &objlen, Int_t &keylen)
1300{
1301 nbytes = 0;
1302 objlen = 0;
1303 keylen = 0;
1304 if (first < fBEGIN) return 0;
1305 if (first > fEND) return 0;
1306 Seek(first);
1307 Int_t nread = maxbytes;
1308 if (first+maxbytes > fEND) nread = fEND-maxbytes;
1309 if (nread < 4) {
1310 Warning("GetRecordHeader","%s: parameter maxbytes = %d must be >= 4",
1311 GetName(), nread);
1312 return nread;
1313 }
1314 if (ReadBuffer(buf,nread)) {
1315 // ReadBuffer return kTRUE in case of failure.
1316 Warning("GetRecordHeader","%s: failed to read header data (maxbytes = %d)",
1317 GetName(), nread);
1318 return nread;
1319 }
1320 Version_t versionkey;
1321 Short_t klen;
1322 UInt_t datime;
1323 Int_t nb,olen;
1324 char *buffer = buf;
1325 frombuf(buffer,&nb);
1326 nbytes = nb;
1327 if (nb < 0) return nread;
1328 // const Int_t headerSize = Int_t(sizeof(nb) +sizeof(versionkey) +sizeof(olen) +sizeof(datime) +sizeof(klen));
1329 const Int_t headerSize = 16;
1330 if (nread < headerSize) return nread;
1331 frombuf(buffer, &versionkey);
1332 frombuf(buffer, &olen);
1333 frombuf(buffer, &datime);
1334 frombuf(buffer, &klen);
1335 if (!olen) olen = nbytes-klen;
1336 objlen = olen;
1337 keylen = klen;
1338 return nread;
1339}
1340
1341////////////////////////////////////////////////////////////////////////////////
1342/// Returns the current file size. Returns -1 in case the file could not
1343/// be stat'ed.
1346{
1347 Long64_t size;
1348
1349 if (fArchive && fArchive->GetMember()) {
1351 } else {
1352 Long_t id, flags, modtime;
1353 if (const_cast<TFile*>(this)->SysStat(fD, &id, &size, &flags, &modtime)) { // NOLINT: silence clang-tidy warnings
1354 Error("GetSize", "cannot stat the file %s", GetName());
1355 return -1;
1356 }
1357 }
1358 return size;
1359}
1360
1361////////////////////////////////////////////////////////////////////////////////
1362/// Returns the cached list of StreamerInfos used in this file.
1365{
1367}
1368
1369////////////////////////////////////////////////////////////////////////////////
1370/// See documentation of GetStreamerInfoList for more details.
1371/// This is an internal method which returns the list of streamer infos and also
1372/// information about the success of the operation.
1375{
1377
1378 if (fIsPcmFile) return {nullptr, 1, hash}; // No schema evolution for ROOT PCM files.
1379
1380 TList *list = nullptr;
1381 if (fSeekInfo) {
1382 TDirectory::TContext ctxt(this); // gFile and gDirectory used in ReadObj
1383 auto key = std::make_unique<TKey>(this);
1384 std::vector<char> buffer(fNbytesInfo+1);
1385 auto buf = buffer.data();
1386 Seek(fSeekInfo); // NOLINT: silence clang-tidy warnings
1387 if (ReadBuffer(buf,fNbytesInfo)) { // NOLINT: silence clang-tidy warnings
1388 // ReadBuffer returns kTRUE in case of failure.
1389 Warning("GetRecordHeader","%s: failed to read the StreamerInfo data from disk.",
1390 GetName());
1391 return {nullptr, 1, hash};
1392 }
1393
1394 if (lookupSICache) {
1395 // key data must be excluded from the hash, otherwise the timestamp will
1396 // always lead to unique hashes for each file
1397 hash = fgTsSIHashes.Hash(buf + key->GetKeylen(), fNbytesInfo - key->GetKeylen());
1398 auto si_uids = fgTsSIHashes.Find(hash);
1399 if (si_uids) {
1400 if (gDebug > 0)
1401 Info("GetStreamerInfo", "The streamer info record for file %s has already been treated, skipping it.", GetName());
1402 for(auto uid : *si_uids)
1403 fClassIndex->fArray[uid] = 1;
1404 return {nullptr, 0, hash};
1405 }
1406 }
1407 key->ReadKeyBuffer(buf);
1408 list = dynamic_cast<TList*>(key->ReadObjWithBuffer(buffer.data()));
1409 if (list) list->SetOwner();
1410 } else {
1411 list = (TList*)Get("StreamerInfo"); //for versions 2.26 (never released)
1412 }
1413
1414 if (!list) {
1415 Info("GetStreamerInfoList", "cannot find the StreamerInfo record in file %s",
1416 GetName());
1417 return {nullptr, 1, hash};
1418 }
1419
1420 return {list, 0, hash};
1421}
1422
1423////////////////////////////////////////////////////////////////////////////////
1424/// Read the list of TStreamerInfo objects written to this file.
1425///
1426/// The function returns a TList. It is the user's responsibility
1427/// to delete the list created by this function.
1428///
1429/// Note the list, in addition to TStreamerInfo object, contains sometimes
1430/// a TList named 'listOfRules' and containing the schema evolution rules
1431/// related to the file's content.
1432///
1433/// Using the list, one can access additional information, e.g.:
1434/// ~~~{.cpp}
1435/// TFile f("myfile.root");
1436/// auto list = f.GetStreamerInfoList();
1437/// auto info = dynamic_cast<TStreamerInfo*>(list->FindObject("MyClass"));
1438/// if (info) auto classversionid = info->GetClassVersion();
1439/// delete list;
1440/// ~~~
1441///
1444{
1445 return GetStreamerInfoListImpl(/*lookupSICache*/ false).fList;
1446}
1447
1448////////////////////////////////////////////////////////////////////////////////
1449/// List file contents.
1450///
1451/// Indentation is used to identify the file tree.
1452/// Subdirectories are listed first, then objects in memory,
1453/// then objects on the file.
1455void TFile::ls(Option_t *option) const
1456{
1458 std::cout <<ClassName()<<"**\t\t"<<GetName()<<"\t"<<GetTitle()<<std::endl;
1462}
1463
1464////////////////////////////////////////////////////////////////////////////////
1465/// Returns kTRUE in case file is open and kFALSE if file is not open.
1467Bool_t TFile::IsOpen() const
1468{
1469 return fD == -1 ? kFALSE : kTRUE;
1470}
1471
1472////////////////////////////////////////////////////////////////////////////////
1473/// Mark unused bytes on the file.
1474///
1475/// The list of free segments is in the fFree linked list.
1476/// When an object is deleted from the file, the freed space is added
1477/// into the FREE linked list (fFree). The FREE list consists of a chain
1478/// of consecutive free segments on the file. At the same time, the first
1479/// 4 bytes of the freed record on the file are overwritten by GAPSIZE
1480/// where GAPSIZE = -(Number of bytes occupied by the record).
1482void TFile::MakeFree(Long64_t first, Long64_t last)
1483{
1484 TFree *f1 = (TFree*)fFree->First();
1485 if (!f1) return;
1486 TFree *newfree = f1->AddFree(fFree,first,last);
1487 if(!newfree) return;
1488 Long64_t nfirst = newfree->GetFirst();
1489 Long64_t nlast = newfree->GetLast();
1490 Long64_t nbytesl= nlast-nfirst+1;
1491 if (nbytesl > 2000000000) nbytesl = 2000000000;
1492 Int_t nbytes = -Int_t (nbytesl);
1493 Int_t nb = sizeof(Int_t);
1494 char * buffer = new char[nb];
1495 char * psave = buffer;
1496 tobuf(buffer, nbytes);
1497 if (last == fEND-1) fEND = nfirst;
1498 Seek(nfirst);
1499 // We could not update the meta data for this block on the file.
1500 // This is not fatal as this only means that we won't get it 'right'
1501 // if we ever need to Recover the file before the block is actually
1502 // (attempted to be reused.
1503 // coverity[unchecked_value]
1504 WriteBuffer(psave, nb);
1505 if (fMustFlush) Flush();
1506 delete [] psave;
1507}
1508
1509////////////////////////////////////////////////////////////////////////////////
1510/// List the contents of a file sequentially.
1511/// For each logical record found, it prints:
1512///
1513/// Date/Time Record_Adress Logical_Record_Length ClassName CompressionFactor
1514///
1515/// Example of output
1516///
1517/// 20010404/150437 At:64 N=150 TFile
1518/// 20010404/150440 At:214 N=28326 TBasket CX = 1.13
1519/// 20010404/150440 At:28540 N=29616 TBasket CX = 1.08
1520/// 20010404/150440 At:58156 N=29640 TBasket CX = 1.08
1521/// 20010404/150440 At:87796 N=29076 TBasket CX = 1.10
1522/// 20010404/150440 At:116872 N=10151 TBasket CX = 3.15
1523/// 20010404/150441 At:127023 N=28341 TBasket CX = 1.13
1524/// 20010404/150441 At:155364 N=29594 TBasket CX = 1.08
1525/// 20010404/150441 At:184958 N=29616 TBasket CX = 1.08
1526/// 20010404/150441 At:214574 N=29075 TBasket CX = 1.10
1527/// 20010404/150441 At:243649 N=9583 TBasket CX = 3.34
1528/// 20010404/150442 At:253232 N=28324 TBasket CX = 1.13
1529/// 20010404/150442 At:281556 N=29641 TBasket CX = 1.08
1530/// 20010404/150442 At:311197 N=29633 TBasket CX = 1.08
1531/// 20010404/150442 At:340830 N=29091 TBasket CX = 1.10
1532/// 20010404/150442 At:369921 N=10341 TBasket CX = 3.09
1533/// 20010404/150442 At:380262 N=509 TH1F CX = 1.93
1534/// 20010404/150442 At:380771 N=1769 TH2F CX = 4.32
1535/// 20010404/150442 At:382540 N=1849 TProfile CX = 1.65
1536/// 20010404/150442 At:384389 N=18434 TNtuple CX = 4.51
1537/// 20010404/150442 At:402823 N=307 KeysList
1538/// 20010404/150443 At:403130 N=4548 StreamerInfo CX = 3.65
1539/// 20010404/150443 At:407678 N=86 FreeSegments
1540/// 20010404/150443 At:407764 N=1 END
1541///
1542/// If the parameter opt contains "forComp", the Date/Time is omitted
1543/// and the decompressed size is also printed.
1544///
1545/// Record_Adress Logical_Record_Length Key_Length Object_Record_Length ClassName CompressionFactor
1546///
1547/// If the parameter opt contains "extended", the name and title of the keys are added:
1548/// 20200820/155031 At:100 N=180 TFile name: hsimple.root title: Demo ROOT file with histograms
1549/// 220200820/155032 At:280 N=28880 TBasket CX = 1.11 name: random title: ntuple
1550/// 220200820/155032 At:29160 N=29761 TBasket CX = 1.08 name: px title: ntuple
1551/// 220200820/155032 At:58921 N=29725 TBasket CX = 1.08 name: py title: ntuple
1552/// 220200820/155032 At:88646 N=29209 TBasket CX = 1.10 name: pz title: ntuple
1553/// 220200820/155032 At:117855 N=10197 TBasket CX = 3.14 name: i title: ntuple
1554/// ...
1555/// 20200820/155032 At:405110 N=808 TNtuple CX = 3.53 name: ntuple title: Demo ntuple
1556/// 20200820/155706 At:405918 N=307 KeysList name: hsimple.root title: Demo ROOT file with histograms
1557/// 20200820/155032 At:406225 N=8556 StreamerInfo CX = 3.42 name: StreamerInfo title: Doubly linked list
1558/// 20200820/155708 At:414781 N=86 FreeSegments name: hsimple.root title: Demo ROOT file with histograms
1559/// 20200820/155708 At:414867 N=1 END
1560///
1561/// Note: The combined size of the classname, name and title is truncated to 476 characters (a little more for regular keys of small files)
1562///
1563
1565void TFile::Map(Option_t *opt)
1566{
1567 TString options(opt);
1568 options.ToLower();
1569 bool forComp = options.Contains("forcomp");
1570 bool extended = options.Contains("extended");
1571
1572 Short_t keylen,cycle;
1573 UInt_t datime;
1574 Int_t nbytes,date,time,objlen;
1575 date = 0;
1576 time = 0;
1577 Long64_t seekkey,seekpdir;
1578 char *buffer;
1579 char nwhc;
1580 Long64_t idcur = fBEGIN;
1581
1582 constexpr Int_t nwheader = 512;
1583
1584 char header[nwheader];
1585 char classname[512];
1586 char keyname[512];
1587 char keytitle[512];
1588 TString extrainfo;
1589
1590 unsigned char nDigits = std::log10(fEND) + 1;
1591
1592 while (idcur < fEND) {
1593 Seek(idcur);
1594 Int_t nread = nwheader;
1595 if (idcur+nread >= fEND) nread = fEND-idcur-1;
1596 if (ReadBuffer(header, nread)) {
1597 // ReadBuffer returns kTRUE in case of failure.
1598 Warning("Map","%s: failed to read the key data from disk at %lld.",
1599 GetName(),idcur);
1600 break;
1601 }
1602
1603 buffer=header;
1604 frombuf(buffer, &nbytes);
1605 if (!nbytes) {
1606 Printf("Address = %lld\tNbytes = %d\t=====E R R O R=======", idcur, nbytes);
1607 date = 0; time = 0;
1608 break;
1609 }
1610 if (nbytes < 0) {
1611 Printf("Address = %lld\tNbytes = %d\t=====G A P===========", idcur, nbytes);
1612 idcur -= nbytes;
1613 Seek(idcur);
1614 continue;
1615 }
1616 Version_t versionkey;
1617 frombuf(buffer, &versionkey);
1618 frombuf(buffer, &objlen);
1619 frombuf(buffer, &datime);
1620 frombuf(buffer, &keylen);
1621 frombuf(buffer, &cycle);
1622 if (versionkey > 1000) {
1623 frombuf(buffer, &seekkey);
1624 frombuf(buffer, &seekpdir);
1625 } else {
1626 Int_t skey,sdir;
1627 frombuf(buffer, &skey); seekkey = (Long64_t)skey;
1628 frombuf(buffer, &sdir); seekpdir = (Long64_t)sdir;
1629 }
1630 frombuf(buffer, &nwhc);
1631 if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1632 nwhc = nwheader - (buffer-header);
1633 for (int i = 0;i < nwhc; i++) frombuf(buffer, &classname[i]);
1634 classname[(int)nwhc] = '\0'; //cast to avoid warning with gcc3.4
1635 if (idcur == fSeekFree) strlcpy(classname,"FreeSegments",512);
1636 if (idcur == fSeekInfo) strlcpy(classname,"StreamerInfo",512);
1637 if (idcur == fSeekKeys) strlcpy(classname,"KeysList",512);
1638
1639 if (extended) {
1640 if ( (buffer-header) >= nwheader )
1641 nwhc = 0;
1642 else {
1643 frombuf(buffer, &nwhc);
1644 if (nwhc < 0)
1645 nwhc = 0;
1646 else if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1647 nwhc = nwheader - (buffer-header);
1648 }
1649 for (int i = 0;i < nwhc; i++) frombuf(buffer, &keyname[i]);
1650 keyname[(int)nwhc] = '\0'; //cast to avoid warning with gcc3.4
1651
1652 if ( (buffer-header) >= nwheader )
1653 nwhc = 0;
1654 else {
1655 frombuf(buffer, &nwhc);
1656 if (nwhc < 0)
1657 nwhc = 0;
1658 else if ( ((buffer-header) + nwhc) > nwheader ) // Don't read past the end of the part of the key we have read.
1659 nwhc = nwheader - (buffer-header);
1660 }
1661 for (int i = 0;i < nwhc; i++) frombuf(buffer, &keytitle[i]);
1662 keytitle[(int)nwhc] = '\0'; //cast to avoid warning with gcc3.4
1663
1664 extrainfo.Form(" name: %-16s title: %s", keyname, keytitle);
1665 }
1666
1667 TDatime::GetDateTime(datime, date, time);
1668 if (!forComp) {
1669 if (objlen != nbytes - keylen) {
1670 Float_t cx = Float_t(objlen + keylen) / Float_t(nbytes);
1671 Printf("%d/%06d At:%-*lld N=%-8d %-14s CX = %5.2f %s", date, time, nDigits + 1, idcur, nbytes, classname,
1672 cx, extrainfo.Data());
1673 } else {
1674 Printf("%d/%06d At:%-*lld N=%-8d %-14s %s", date, time, nDigits + 1, idcur, nbytes, classname, extrainfo.Data());
1675 }
1676 } else {
1677 // Printing to help compare two files.
1678 if (objlen != nbytes - keylen) {
1679 Float_t cx = Float_t(objlen + keylen) / Float_t(nbytes);
1680 Printf("At:%-*lld N=%-8d K=%-3d O=%-8d %-14s CX = %5.2f %s", nDigits+1, idcur, nbytes, keylen, objlen, classname, cx, extrainfo.Data());
1681 } else {
1682 Printf("At:%-*lld N=%-8d K=%-3d O=%-8d %-14s CX = 1 %s", nDigits+1, idcur, nbytes, keylen, objlen, classname, extrainfo.Data());
1683 }
1684 }
1685 idcur += nbytes;
1686 }
1687 if (!forComp)
1688 Printf("%d/%06d At:%-*lld N=%-8d %-14s",date,time, nDigits+1, idcur,1,"END");
1689 else
1690 Printf("At:%-*lld N=%-8d K= O= %-14s", nDigits+1, idcur,1,"END");
1691}
1692
1693////////////////////////////////////////////////////////////////////////////////
1694/// Paint all objects in the file.
1697{
1698 GetList()->R__FOR_EACH(TObject,Paint)(option);
1699}
1700
1701////////////////////////////////////////////////////////////////////////////////
1702/// Print all objects in the file.
1704void TFile::Print(Option_t *option) const
1705{
1706 Printf("TFile: name=%s, title=%s, option=%s", GetName(), GetTitle(), GetOption());
1707 GetList()->R__FOR_EACH(TObject,Print)(option);
1708}
1709
1710////////////////////////////////////////////////////////////////////////////////
1711/// Read a buffer from the file at the offset 'pos' in the file.
1712///
1713/// Returns kTRUE in case of failure.
1714/// Compared to ReadBuffer(char*, Int_t), this routine does _not_
1715/// change the cursor on the physical file representation (fD)
1716/// if the data is in this TFile's cache.
1718Bool_t TFile::ReadBuffer(char *buf, Long64_t pos, Int_t len)
1719{
1720 if (IsOpen()) {
1721
1722 SetOffset(pos);
1723
1724 Int_t st;
1725 Double_t start = 0;
1726 if (gPerfStats) start = TTimeStamp();
1727
1728 if ((st = ReadBufferViaCache(buf, len))) {
1729 if (st == 2)
1730 return kTRUE;
1731 return kFALSE;
1732 }
1733
1734 Seek(pos);
1735 ssize_t siz;
1736
1737 while ((siz = SysRead(fD, buf, len)) < 0 && GetErrno() == EINTR)
1738 ResetErrno();
1739
1740 if (siz < 0) {
1741 SysError("ReadBuffer", "error reading from file %s", GetName());
1742 return kTRUE;
1743 }
1744 if (siz != len) {
1745 Error("ReadBuffer", "error reading all requested bytes from file %s, got %ld of %d",
1746 GetName(), (Long_t)siz, len);
1747 return kTRUE;
1748 }
1749 fBytesRead += siz;
1750 fgBytesRead += siz;
1751 fReadCalls++;
1752 fgReadCalls++;
1753
1756 if (gPerfStats) {
1757 gPerfStats->FileReadEvent(this, len, start);
1758 }
1759 return kFALSE;
1760 }
1761 return kTRUE;
1762}
1763
1764////////////////////////////////////////////////////////////////////////////////
1765/// Read a buffer from the file. This is the basic low level read operation.
1766/// Returns kTRUE in case of failure.
1769{
1770 if (IsOpen()) {
1771
1772 Int_t st;
1773 if ((st = ReadBufferViaCache(buf, len))) {
1774 if (st == 2)
1775 return kTRUE;
1776 return kFALSE;
1777 }
1778
1779 ssize_t siz;
1780 Double_t start = 0;
1781
1782 if (gPerfStats) start = TTimeStamp();
1783
1784 while ((siz = SysRead(fD, buf, len)) < 0 && GetErrno() == EINTR)
1785 ResetErrno();
1786
1787 if (siz < 0) {
1788 SysError("ReadBuffer", "error reading from file %s", GetName());
1789 return kTRUE;
1790 }
1791 if (siz != len) {
1792 Error("ReadBuffer", "error reading all requested bytes from file %s, got %ld of %d",
1793 GetName(), (Long_t)siz, len);
1794 return kTRUE;
1795 }
1796 fBytesRead += siz;
1797 fgBytesRead += siz;
1798 fReadCalls++;
1799 fgReadCalls++;
1800
1803 if (gPerfStats) {
1804 gPerfStats->FileReadEvent(this, len, start);
1805 }
1806 return kFALSE;
1807 }
1808 return kTRUE;
1809}
1810
1811////////////////////////////////////////////////////////////////////////////////
1812/// Read the nbuf blocks described in arrays pos and len.
1813///
1814/// The value pos[i] is the seek position of block i of length len[i].
1815/// Note that for nbuf=1, this call is equivalent to TFile::ReafBuffer.
1816/// This function is overloaded by TNetFile, TWebFile, etc.
1817/// Returns kTRUE in case of failure.
1819Bool_t TFile::ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
1820{
1821 // called with buf=0, from TFileCacheRead to pass list of readahead buffers
1822 if (!buf) {
1823 for (Int_t j = 0; j < nbuf; j++) {
1824 if (ReadBufferAsync(pos[j], len[j])) {
1825 return kTRUE;
1826 }
1827 }
1828 return kFALSE;
1829 }
1830
1831 Int_t k = 0;
1834 fCacheRead = nullptr;
1835 Long64_t curbegin = pos[0];
1836 Long64_t cur;
1837 char *buf2 = nullptr;
1838 Int_t i = 0, n = 0;
1839 while (i < nbuf) {
1840 cur = pos[i]+len[i];
1841 Bool_t bigRead = kTRUE;
1842 if (cur -curbegin < fgReadaheadSize) {n++; i++; bigRead = kFALSE;}
1843 if (bigRead || (i>=nbuf)) {
1844 if (n == 0) {
1845 //if the block to read is about the same size as the read-ahead buffer
1846 //we read the block directly
1847 Seek(pos[i]);
1848 result = ReadBuffer(&buf[k], len[i]);
1849 if (result) break;
1850 k += len[i];
1851 i++;
1852 } else {
1853 //otherwise we read all blocks that fit in the read-ahead buffer
1854 Seek(curbegin);
1855 if (!buf2) buf2 = new char[fgReadaheadSize];
1856 //we read ahead
1857 Long64_t nahead = pos[i-1]+len[i-1]-curbegin;
1858 result = ReadBuffer(buf2, nahead);
1859 if (result) break;
1860 //now copy from the read-ahead buffer to the cache
1861 Int_t kold = k;
1862 for (Int_t j=0;j<n;j++) {
1863 memcpy(&buf[k],&buf2[pos[i-n+j]-curbegin],len[i-n+j]);
1864 k += len[i-n+j];
1865 }
1866 Int_t nok = k-kold;
1867 Long64_t extra = nahead-nok;
1868 fBytesReadExtra += extra;
1869 fBytesRead -= extra;
1870 fgBytesRead -= extra;
1871 n = 0;
1872 }
1873 curbegin = i < nbuf ? pos[i] : 0;
1874 }
1875 }
1876 if (buf2) delete [] buf2;
1877 fCacheRead = old;
1878 return result;
1879}
1880
1881////////////////////////////////////////////////////////////////////////////////
1882/// Read buffer via cache.
1883///
1884/// Returns 0 if the requested block is not in the cache, 1 in case read via
1885/// cache was successful, 2 in case read via cache failed.
1888{
1889 Long64_t off = GetRelOffset();
1890 if (fCacheRead) {
1891 Int_t st = fCacheRead->ReadBuffer(buf, off, len);
1892 if (st < 0)
1893 return 2; // failure reading
1894 else if (st == 1) {
1895 // fOffset might have been changed via TFileCacheRead::ReadBuffer(), reset it
1896 SetOffset(off + len);
1897 return 1;
1898 }
1899 // fOffset might have been changed via TFileCacheRead::ReadBuffer(), reset it
1900 Seek(off);
1901 } else {
1902 // if write cache is active check if data still in write cache
1903 if (fWritable && fCacheWrite) {
1904 if (fCacheWrite->ReadBuffer(buf, off, len) == 0) {
1905 SetOffset(off + len);
1906 return 1;
1907 }
1908 // fOffset might have been changed via TFileCacheWrite::ReadBuffer(), reset it
1909 SetOffset(off);
1910 }
1911 }
1912
1913 return 0;
1914}
1915
1916////////////////////////////////////////////////////////////////////////////////
1917/// Read the FREE linked list.
1918///
1919/// Every file has a linked list (fFree) of free segments.
1920/// This linked list has been written on the file via WriteFree
1921/// as a single data record.
1923void TFile::ReadFree()
1924{
1925 // Avoid problem with file corruption.
1926 if (fNbytesFree < 0 || fNbytesFree > fEND) {
1927 fNbytesFree = 0;
1928 return;
1929 }
1930 TKey *headerfree = new TKey(fSeekFree, fNbytesFree, this);
1931 headerfree->ReadFile();
1932 char *buffer = headerfree->GetBuffer();
1933 headerfree->ReadKeyBuffer(buffer);
1934 buffer = headerfree->GetBuffer();
1935 while (1) {
1936 TFree *afree = new TFree();
1937 afree->ReadBuffer(buffer);
1938 fFree->Add(afree);
1939 if (afree->GetLast() > fEND) break;
1940 }
1941 delete headerfree;
1942}
1943
1944////////////////////////////////////////////////////////////////////////////////
1945/// The TProcessID with number pidf is read from this file.
1946///
1947/// If the object is not already entered in the gROOT list, it is added.
1950{
1951 TProcessID *pid = nullptr;
1953 if (pidf < pids->GetSize()) pid = (TProcessID *)pids->UncheckedAt(pidf);
1954 if (pid) {
1955 pid->CheckInit();
1956 return pid;
1957 }
1958
1959 //check if fProcessIDs[uid] is set in file
1960 //if not set, read the process uid from file
1961 char pidname[32];
1962 snprintf(pidname,32,"ProcessID%d",pidf);
1963 pid = (TProcessID *)Get(pidname);
1964 if (gDebug > 0) {
1965 printf("ReadProcessID, name=%s, file=%s, pid=%zx\n",pidname,GetName(),(size_t)pid);
1966 }
1967 if (!pid) {
1968 //file->Error("ReadProcessID","Cannot find %s in file %s",pidname,file->GetName());
1969 return pid;
1970 }
1971
1972 //check that a similar pid is not already registered in fgPIDs
1973 TObjArray *pidslist = TProcessID::GetPIDs();
1974 TIter next(pidslist);
1975 TProcessID *p;
1976 bool found = false;
1977
1978 {
1980 while ((p = (TProcessID*)next())) {
1981 if (!strcmp(p->GetTitle(),pid->GetTitle())) {
1982 found = true;
1983 break;
1984 }
1985 }
1986 }
1987
1988 if (found) {
1989 delete pid;
1990 pids->AddAtAndExpand(p,pidf);
1991 p->IncrementCount();
1992 return p;
1993 }
1994
1995 pids->AddAtAndExpand(pid,pidf);
1996 pid->IncrementCount();
1997
1998 {
2000 pidslist->Add(pid);
2001 Int_t ind = pidslist->IndexOf(pid);
2002 pid->SetUniqueID((UInt_t)ind);
2003 }
2004
2005 return pid;
2006}
2007
2008
2009////////////////////////////////////////////////////////////////////////////////
2010/// Attempt to recover file if not correctly closed
2011///
2012/// The function returns the number of keys that have been recovered.
2013/// If no keys can be recovered, the file will be declared Zombie by
2014/// the calling function. This function is automatically called when
2015/// opening a file.
2016/// If the file is open in read only mode, the file is not modified.
2017/// If open in update mode and the function finds something to recover,
2018/// a new directory header is written to the file. When opening the file gain
2019/// no message from Recover will be reported.
2020/// If keys have been recovered, the file is usable and you can safely
2021/// read the corresponding objects.
2022/// If the file is not usable (a zombie), you can test for this case
2023/// with code like:
2024///
2025/// ~~~{.cpp}
2026/// TFile f("myfile.root");
2027/// if (f.IsZombie()) {<actions to take if file is unusable>}
2028/// ~~~
2029///
2030/// If the file has been recovered, the bit kRecovered is set in the TFile object in memory.
2031/// You can test if the file has been recovered with
2032///
2033/// if (f.TestBit(TFile::kRecovered)) {... the file has been recovered}
2034///
2035/// When writing TTrees to a file, it is important to save the Tree header
2036/// at regular intervals (see TTree::AutoSave). If a file containing a Tree
2037/// is recovered, the last Tree header written to the file will be used.
2038/// In this case all the entries in all the branches written before writing
2039/// the header are valid entries.
2040/// One can disable the automatic recovery procedure by setting
2041///
2042/// TFile.Recover 0
2043///
2044/// in the <em>system.rootrc</em> file.
2047{
2048 Short_t keylen,cycle;
2049 UInt_t datime;
2050 Int_t nbytes,date,time,objlen,nwheader;
2051 Long64_t seekkey,seekpdir;
2052 char header[1024];
2053 char *buffer, *bufread;
2054 char nwhc;
2055 Long64_t idcur = fBEGIN;
2056
2057 Long64_t size;
2058 if ((size = GetSize()) == -1) { // NOLINT: silence clang-tidy warnings
2059 Error("Recover", "cannot stat the file %s", GetName());
2060 return 0;
2061 }
2062
2063 fEND = Long64_t(size);
2064
2065 if (fWritable && !fFree) fFree = new TList;
2066
2067 TKey *key;
2068 Int_t nrecov = 0;
2069 nwheader = 1024;
2070 Int_t nread = nwheader;
2071
2072 while (idcur < fEND) {
2073 Seek(idcur); // NOLINT: silence clang-tidy warnings
2074 if (idcur+nread >= fEND) nread = fEND-idcur-1;
2075 if (ReadBuffer(header, nread)) { // NOLINT: silence clang-tidy warnings
2076 // ReadBuffer returns kTRUE in case of failure.
2077 Error("Recover","%s: failed to read the key data from disk at %lld.",
2078 GetName(),idcur);
2079 break;
2080 }
2081 buffer = header;
2082 bufread = header;
2083 frombuf(buffer, &nbytes);
2084 if (!nbytes) {
2085 Error("Recover","Address = %lld\tNbytes = %d\t=====E R R O R=======", idcur, nbytes);
2086 break;
2087 }
2088 if (nbytes < 0) {
2089 idcur -= nbytes;
2090 if (fWritable) new TFree(fFree,idcur,idcur-nbytes-1);
2091 Seek(idcur);
2092 continue;
2093 }
2094 Version_t versionkey;
2095 frombuf(buffer, &versionkey);
2096 frombuf(buffer, &objlen);
2097 frombuf(buffer, &datime);
2098 frombuf(buffer, &keylen);
2099 frombuf(buffer, &cycle);
2100 if (versionkey > 1000) {
2101 frombuf(buffer, &seekkey);
2102 frombuf(buffer, &seekpdir);
2103 } else {
2104 Int_t skey,sdir;
2105 frombuf(buffer, &skey); seekkey = (Long64_t)skey;
2106 frombuf(buffer, &sdir); seekpdir = (Long64_t)sdir;
2107 }
2108 frombuf(buffer, &nwhc);
2109 char *classname = nullptr;
2110 if (nwhc <= 0 || nwhc > 100) break;
2111 classname = new char[nwhc+1];
2112 int i, nwhci = nwhc;
2113 for (i = 0;i < nwhc; i++) frombuf(buffer, &classname[i]);
2114 classname[nwhci] = '\0';
2115 TDatime::GetDateTime(datime, date, time);
2116 TClass *tclass = TClass::GetClass(classname);
2117 if (seekpdir == fSeekDir && tclass && !tclass->InheritsFrom(TFile::Class())
2118 && strcmp(classname,"TBasket")) {
2119 key = new TKey(this);
2120 key->ReadKeyBuffer(bufread);
2121 if (!strcmp(key->GetName(),"StreamerInfo")) {
2122 fSeekInfo = seekkey;
2124 fNbytesInfo = nbytes;
2125 } else {
2126 AppendKey(key);
2127 nrecov++;
2129 Info("Recover", "%s, recovered key %s:%s at address %lld",GetName(),key->GetClassName(),key->GetName(),idcur);
2130 }
2131 }
2132 delete [] classname;
2133 idcur += nbytes;
2134 }
2135 if (fWritable) {
2136 Long64_t max_file_size = Long64_t(kStartBigFile);
2137 if (max_file_size < fEND) max_file_size = fEND+1000000000;
2138 TFree *last = (TFree*)fFree->Last();
2139 if (last) {
2140 last->AddFree(fFree,fEND,max_file_size);
2141 } else {
2142 new TFree(fFree,fEND,max_file_size);
2143 }
2144 if (nrecov) Write();
2145 }
2146 return nrecov;
2147}
2148
2149////////////////////////////////////////////////////////////////////////////////
2150/// Reopen a file with a different access mode.
2151///
2152/// For example, it is possible to change from READ to
2153/// UPDATE or from NEW, CREATE, RECREATE, UPDATE to READ. Thus the
2154/// mode argument can be either "READ" or "UPDATE". The method returns
2155/// 0 in case the mode was successfully modified, 1 in case the mode
2156/// did not change (was already as requested or wrong input arguments)
2157/// and -1 in case of failure, in which case the file cannot be used
2158/// anymore. The current directory (gFile) is changed to this file.
2161{
2162 cd();
2163
2164 TString opt = mode;
2165 opt.ToUpper();
2166
2167 if (opt != "READ" && opt != "UPDATE") {
2168 Error("ReOpen", "mode must be either READ or UPDATE, not %s", opt.Data());
2169 return 1;
2170 }
2171
2172 if (opt == fOption || (opt == "UPDATE" && fOption == "CREATE"))
2173 return 1;
2174
2175 if (opt == "READ") {
2176 // switch to READ mode
2177
2178 // flush data still in the pipeline and close the file
2179 if (IsOpen() && IsWritable()) {
2181
2182 // save directory key list and header
2183 Save();
2184
2185 TFree *f1 = (TFree*)fFree->First();
2186 if (f1) {
2187 WriteFree(); // write free segments linked list
2188 WriteHeader(); // now write file header
2189 }
2190
2192
2193 // delete free segments from free list
2194 fFree->Delete();
2196
2197 SysClose(fD);
2198 fD = -1;
2199
2201 }
2202
2203 // open in READ mode
2204 fOption = opt; // set fOption before SysOpen() for TNetFile
2205#ifndef WIN32
2206 fD = SysOpen(fRealName, O_RDONLY, 0644);
2207#else
2208 fD = SysOpen(fRealName, O_RDONLY | O_BINARY, S_IREAD | S_IWRITE);
2209#endif
2210 if (fD == -1) {
2211 SysError("ReOpen", "file %s can not be opened in read mode", GetName());
2212 return -1;
2213 }
2215
2216 } else {
2217 // switch to UPDATE mode
2218
2219 // close readonly file
2220 if (IsOpen()) {
2221 SysClose(fD);
2222 fD = -1;
2223 }
2224
2225 // open in UPDATE mode
2226 fOption = opt; // set fOption before SysOpen() for TNetFile
2227#ifndef WIN32
2228 fD = SysOpen(fRealName, O_RDWR | O_CREAT, 0644);
2229#else
2230 fD = SysOpen(fRealName, O_RDWR | O_CREAT | O_BINARY, S_IREAD | S_IWRITE);
2231#endif
2232 if (fD == -1) {
2233 SysError("ReOpen", "file %s can not be opened in update mode", GetName());
2234 return -1;
2235 }
2237
2238 fFree = new TList;
2239 if (fSeekFree > fBEGIN)
2240 ReadFree();
2241 else
2242 Warning("ReOpen","file %s probably not closed, cannot read free segments", GetName());
2243 }
2244
2245 return 0;
2246}
2247
2248////////////////////////////////////////////////////////////////////////////////
2249/// Set position from where to start reading.
2252{
2253 switch (pos) {
2254 case kBeg:
2256 break;
2257 case kCur:
2258 fOffset += offset;
2259 break;
2260 case kEnd:
2261 // this option is not used currently in the ROOT code
2262 if (fArchiveOffset)
2263 Error("SetOffset", "seeking from end in archive is not (yet) supported");
2264 fOffset = fEND + offset; // is fEND really EOF or logical EOF?
2265 break;
2266 }
2267}
2268
2269////////////////////////////////////////////////////////////////////////////////
2270/// Seek to a specific position in the file. Pos it either kBeg, kCur or kEnd.
2273{
2274 int whence = 0;
2275 switch (pos) {
2276 case kBeg:
2277 whence = SEEK_SET;
2279 break;
2280 case kCur:
2281 whence = SEEK_CUR;
2282 break;
2283 case kEnd:
2284 whence = SEEK_END;
2285 // this option is not used currently in the ROOT code
2286 if (fArchiveOffset)
2287 Error("Seek", "seeking from end in archive is not (yet) supported");
2288 break;
2289 }
2290 Long64_t retpos;
2291 if ((retpos = SysSeek(fD, offset, whence)) < 0) // NOLINT: silence clang-tidy warnings
2292 SysError("Seek", "cannot seek to position %lld in file %s, retpos=%lld",
2293 offset, GetName(), retpos);
2294
2295 // used by TFileCacheRead::ReadBuffer()
2296 fOffset = retpos;
2297}
2298
2299////////////////////////////////////////////////////////////////////////////////
2300/// See comments for function SetCompressionSettings
2301///
2304{
2305 if (algorithm < 0 || algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined) algorithm = 0;
2306 if (fCompress < 0) {
2308 } else {
2309 int level = fCompress % 100;
2310 fCompress = 100 * algorithm + level;
2311 }
2312}
2313
2314////////////////////////////////////////////////////////////////////////////////
2315/// See comments for function SetCompressionSettings
2318{
2319 if (level < 0) level = 0;
2320 if (level > 99) level = 99;
2321 if (fCompress < 0) {
2322 // if the algorithm is not defined yet use 0 as a default
2323 fCompress = level;
2324 } else {
2325 int algorithm = fCompress / 100;
2326 if (algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined) algorithm = 0;
2327 fCompress = 100 * algorithm + level;
2328 }
2329}
2330
2331////////////////////////////////////////////////////////////////////////////////
2332/// Used to specify the compression level and algorithm.
2333///
2334/// See the TFile constructor for the details.
2337{
2338 fCompress = settings;
2339}
2340
2341////////////////////////////////////////////////////////////////////////////////
2342/// Set a pointer to the read cache.
2343///
2344/// <b>This relinquishes ownership</b> of the previous cache, so if you do not
2345/// already have a pointer to the previous cache (and there was a previous
2346/// cache), you ought to retrieve (and delete it if needed) using:
2347///
2348/// TFileCacheRead *older = myfile->GetCacheRead();
2349///
2350/// The action specifies how to behave when detaching a cache from the
2351/// the TFile. If set to (default) kDisconnect, the contents of the cache
2352/// will be flushed when it is removed from the file, and it will disconnect
2353/// the cache object from the file. In almost all cases, this is what you want.
2354/// If you want to disconnect the cache temporarily from this tree and re-attach
2355/// later to the same fil, you can set action to kDoNotDisconnect. This will allow
2356/// things like prefetching to continue in the background while it is no longer the
2357/// default cache for the TTree. Except for a few expert use cases, kDisconnect is
2358/// likely the correct setting.
2359///
2360/// WARNING: if action=kDoNotDisconnect, you MUST delete the cache before TFile.
2361///
2363void TFile::SetCacheRead(TFileCacheRead *cache, TObject* tree, ECacheAction action)
2364{
2365 if (tree) {
2366 if (cache) fCacheReadMap->Add(tree, cache);
2367 else {
2368 // The only addition to fCacheReadMap is via an interface that takes
2369 // a TFileCacheRead* so the C-cast is safe.
2371 fCacheReadMap->Remove(tree);
2372 if (tpf && (tpf->GetFile() == this) && (action != kDoNotDisconnect)) tpf->SetFile(0, action);
2373 }
2374 }
2375 if (cache) cache->SetFile(this, action);
2376 else if (!tree && fCacheRead && (action != kDoNotDisconnect)) fCacheRead->SetFile(0, action);
2377 // For backward compatibility the last Cache set is the default cache.
2378 fCacheRead = cache;
2379}
2380
2381////////////////////////////////////////////////////////////////////////////////
2382/// Set a pointer to the write cache.
2383///
2384/// If file is null the existing write cache is deleted.
2387{
2388 if (!cache && fCacheWrite) delete fCacheWrite;
2389 fCacheWrite = cache;
2390}
2391
2392////////////////////////////////////////////////////////////////////////////////
2393/// Return the size in bytes of the file header.
2395Int_t TFile::Sizeof() const
2396{
2397 return 0;
2398}
2399
2400////////////////////////////////////////////////////////////////////////////////
2401/// Stream a TFile object.
2404{
2405 if (b.IsReading()) {
2406 b.ReadVersion(); //Version_t v = b.ReadVersion();
2407 } else {
2408 b.WriteVersion(TFile::IsA());
2409 }
2410}
2411
2412////////////////////////////////////////////////////////////////////////////////
2413/// Increment statistics for buffer sizes of objects in this file.
2415void TFile::SumBuffer(Int_t bufsize)
2416{
2417 fWritten++;
2418 fSumBuffer += double(bufsize);
2419 fSum2Buffer += double(bufsize) * double(bufsize); // avoid reaching MAXINT for temporary
2420}
2421
2422////////////////////////////////////////////////////////////////////////////////
2423/// Write memory objects to this file.
2424///
2425/// Loop on all objects in memory (including subdirectories).
2426/// A new key is created in the KEYS linked list for each object.
2427/// The list of keys is then saved on the file (via WriteKeys)
2428/// as a single data record.
2429/// For values of opt see TObject::Write().
2430/// The directory header info is rewritten on the directory header record.
2431/// The linked list of FREE segments is written.
2432/// The file header is written (bytes 1->fBEGIN).
2434Int_t TFile::Write(const char *, Int_t opt, Int_t bufsiz)
2435{
2436 if (!IsWritable()) {
2437 if (!TestBit(kWriteError)) {
2438 // Do not print the warning if we already had a SysError.
2439 Warning("Write", "file %s not opened in write mode", GetName());
2440 }
2441 return 0;
2442 }
2443
2444 if (gDebug) {
2445 if (!GetTitle() || strlen(GetTitle()) == 0)
2446 Info("Write", "writing name = %s", GetName());
2447 else
2448 Info("Write", "writing name = %s title = %s", GetName(), GetTitle());
2449 }
2450
2452 Int_t nbytes = TDirectoryFile::Write(0, opt, bufsiz); // Write directory tree
2454 WriteFree(); // Write free segments linked list
2455 WriteHeader(); // Now write file header
2456 fMustFlush = kTRUE;
2457
2458 return nbytes;
2459}
2460
2461////////////////////////////////////////////////////////////////////////////////
2462/// One can not save a const TDirectory object.
2464Int_t TFile::Write(const char *n, Int_t opt, Int_t bufsize) const
2465{
2466 Error("Write const","A const TFile object should not be saved. We try to proceed anyway.");
2467 return const_cast<TFile*>(this)->Write(n, opt, bufsize);
2468}
2469
2470////////////////////////////////////////////////////////////////////////////////
2471/// Write a buffer to the file. This is the basic low level write operation.
2472/// Returns kTRUE in case of failure.
2474Bool_t TFile::WriteBuffer(const char *buf, Int_t len)
2475{
2476 if (IsOpen() && fWritable) {
2477
2478 Int_t st;
2479 if ((st = WriteBufferViaCache(buf, len))) {
2480 if (st == 2)
2481 return kTRUE;
2482 return kFALSE;
2483 }
2484
2485 ssize_t siz;
2487 while ((siz = SysWrite(fD, buf, len)) < 0 && GetErrno() == EINTR) // NOLINT: silence clang-tidy warnings
2488 ResetErrno(); // NOLINT: silence clang-tidy warnings
2490 if (siz < 0) {
2491 // Write the system error only once for this file
2493 SysError("WriteBuffer", "error writing to file %s (%ld)", GetName(), (Long_t)siz);
2494 return kTRUE;
2495 }
2496 if (siz != len) {
2498 Error("WriteBuffer", "error writing all requested bytes to file %s, wrote %ld of %d",
2499 GetName(), (Long_t)siz, len);
2500 return kTRUE;
2501 }
2502 fBytesWrite += siz;
2503 fgBytesWrite += siz;
2504
2507
2508 return kFALSE;
2509 }
2510 return kTRUE;
2511}
2512
2513////////////////////////////////////////////////////////////////////////////////
2514/// Write buffer via cache. Returns 0 if cache is not active, 1 in case
2515/// write via cache was successful, 2 in case write via cache failed.
2517Int_t TFile::WriteBufferViaCache(const char *buf, Int_t len)
2518{
2519 if (!fCacheWrite) return 0;
2520
2521 Int_t st;
2522 Long64_t off = GetRelOffset();
2523 if ((st = fCacheWrite->WriteBuffer(buf, off, len)) < 0) {
2525 Error("WriteBuffer", "error writing to cache");
2526 return 2;
2527 }
2528 if (st > 0) {
2529 // fOffset might have been changed via TFileCacheWrite::WriteBuffer(), reset it
2530 Seek(off + len);
2531 return 1;
2532 }
2533 return 0;
2534}
2535
2536////////////////////////////////////////////////////////////////////////////////
2537/// Write FREE linked list on the file.
2538/// The linked list of FREE segments (fFree) is written as a single data
2539/// record.
2541void TFile::WriteFree()
2542{
2543 //*-* Delete old record if it exists
2544 if (fSeekFree != 0) {
2546 }
2547
2548 Bool_t largeFile = (fEND > TFile::kStartBigFile);
2549
2550 auto createKey = [this]() {
2551 Int_t nbytes = 0;
2552 TFree *afree;
2553 TIter next (fFree);
2554 while ((afree = (TFree*) next())) {
2555 nbytes += afree->Sizeof();
2556 }
2557 if (!nbytes) return (TKey*)nullptr;
2558
2559 TKey *key = new TKey(fName,fTitle,IsA(),nbytes,this);
2560
2561 if (key->GetSeekKey() == 0) {
2562 delete key;
2563 return (TKey*)nullptr;
2564 }
2565 return key;
2566 };
2567
2568 TKey *key = createKey();
2569 if (!key) return;
2570
2571 if (!largeFile && (fEND > TFile::kStartBigFile)) {
2572 // The free block list is large enough to bring the file to larger
2573 // than 2Gb, the references/offsets are now 64bits in the output
2574 // so we need to redo the calculation since the list of free block
2575 // information will not fit in the original size.
2576 key->Delete();
2577 delete key;
2578
2579 key = createKey();
2580 if (!key) return;
2581 }
2582
2583 Int_t nbytes = key->GetObjlen();
2584 char *buffer = key->GetBuffer();
2585 char *start = buffer;
2586
2587 TIter next (fFree);
2588 TFree *afree;
2589 while ((afree = (TFree*) next())) {
2590 // We could 'waste' time here and double check that
2591 // (buffer+afree->Sizeof() < (start+nbytes)
2592 afree->FillBuffer(buffer);
2593 }
2594 auto actualBytes = buffer-start;
2595 if ( actualBytes != nbytes ) {
2596 if (actualBytes < nbytes) {
2597 // Most likely one of the 'free' segment was used to store this
2598 // TKey, so we had one less TFree to store than we planned.
2599 memset(buffer,0,nbytes-actualBytes);
2600 } else {
2601 Error("WriteFree","The free block list TKey wrote more data than expected (%d vs %ld). Most likely there has been an out-of-bound write.",nbytes,(long int)actualBytes);
2602 }
2603 }
2604 fNbytesFree = key->GetNbytes();
2605 fSeekFree = key->GetSeekKey();
2606 key->WriteFile();
2607 delete key;
2608}
2609
2610////////////////////////////////////////////////////////////////////////////////
2611/// Write File Header.
2613void TFile::WriteHeader()
2614{
2616 TFree *lastfree = (TFree*)fFree->Last();
2617 if (lastfree) fEND = lastfree->GetFirst();
2618 const char *root = "root";
2619 char *psave = new char[fBEGIN];
2620 char *buffer = psave;
2621 Int_t nfree = fFree->GetSize();
2622 memcpy(buffer, root, 4); buffer += 4;
2623 Int_t version = fVersion;
2624 if (version <1000000 && fEND > kStartBigFile) {version += 1000000; fUnits = 8;}
2625 tobuf(buffer, version);
2626 tobuf(buffer, (Int_t)fBEGIN);
2627 if (version < 1000000) {
2628 tobuf(buffer, (Int_t)fEND);
2629 tobuf(buffer, (Int_t)fSeekFree);
2630 tobuf(buffer, fNbytesFree);
2631 tobuf(buffer, nfree);
2632 tobuf(buffer, fNbytesName);
2633 tobuf(buffer, fUnits);
2634 tobuf(buffer, fCompress);
2635 tobuf(buffer, (Int_t)fSeekInfo);
2636 tobuf(buffer, fNbytesInfo);
2637 } else {
2638 tobuf(buffer, fEND);
2639 tobuf(buffer, fSeekFree);
2640 tobuf(buffer, fNbytesFree);
2641 tobuf(buffer, nfree);
2642 tobuf(buffer, fNbytesName);
2643 tobuf(buffer, fUnits);
2644 tobuf(buffer, fCompress);
2645 tobuf(buffer, fSeekInfo);
2646 tobuf(buffer, fNbytesInfo);
2647 }
2649 TUUID("00000000-0000-0000-0000-000000000000").FillBuffer(buffer);
2650 else
2651 fUUID.FillBuffer(buffer);
2652 Int_t nbytes = buffer - psave;
2653 Seek(0); // NOLINT: silence clang-tidy warnings
2654 WriteBuffer(psave, nbytes); // NOLINT: silence clang-tidy warnings
2655 Flush(); // NOLINT: silence clang-tidy warnings, Intentionally not conditional on fMustFlush, this is the 'obligatory' flush.
2656 delete [] psave;
2657}
2658
2659////////////////////////////////////////////////////////////////////////////////
2660/// Generate source code necessary to access the objects stored in the file.
2661///
2662/// Generate code in directory dirname for all classes specified in
2663/// argument classes If classes = "*" (default and currently the
2664/// only supported value), the function generates an include file
2665/// for each class in the StreamerInfo list for which a TClass
2666/// object does not exist.
2667///
2668/// The code generated includes:
2669/// - <em>dirnameProjectHeaders.h</em>, which contains one `#include` statement per generated header file
2670/// - <em>dirnameProjectSource.cxx</em>,which contains all the constructors and destructors implementation.
2671/// and one header per class that is not nested inside another class.
2672/// The header file name is the fully qualified name of the class after all the special characters
2673/// "<>,:" are replaced by underscored. For example for std::pair<edm::Vertex,int> the file name is
2674/// pair_edm__Vertex_int_.h
2675///
2676/// In the generated classes, map, multimap when the first template parameter is a class
2677/// are replaced by a vector of pair. set and multiset when the tempalte parameter
2678/// is a class are replaced by a vector. This is required since we do not have the
2679/// code needed to order and/or compare the object of the classes.
2680/// This is a quick explanation of the options available:
2681/// Option | Details
2682/// -------|--------
2683/// new (default) | A new directory dirname is created. If dirname already exist, an error message is printed and the function returns.
2684/// recreate | If dirname does not exist, it is created (like in "new"). If dirname already exist, all existing files in dirname are deleted before creating the new files.
2685/// update | New classes are added to the existing directory. Existing classes with the same name are replaced by the new definition. If the directory dirname doest not exist, same effect as "new".
2686/// genreflex | Use genreflex rather than rootcint to generate the dictionary.
2687/// par | Create a PAR file with the minimal set of code needed to read the content of the ROOT file. The name of the PAR file is basename(dirname), with extension '.par' enforced; the PAR file will be created at dirname(dirname).
2688///
2689/// If, in addition to one of the 3 above options, the option "+" is specified,
2690/// the function will generate:
2691/// - a script called MAKEP to build the shared lib
2692/// - a dirnameLinkDef.h file
2693/// - rootcint will be run to generate a dirnameProjectDict.cxx file
2694/// - dirnameProjectDict.cxx will be compiled with the current options in compiledata.h
2695/// - a shared lib dirname.so will be created.
2696/// If the option "++" is specified, the generated shared lib is dynamically
2697/// linked with the current executable module.
2698/// If the option "+" and "nocompile" are specified, the utility files are generated
2699/// as in the option "+" but they are not executed.
2700/// Example:
2701/// file.MakeProject("demo","*","recreate++");
2702/// - creates a new directory demo unless it already exist
2703/// - clear the previous directory content
2704/// - generate the xxx.h files for all classes xxx found in this file
2705/// and not yet known to the CINT dictionary.
2706/// - creates the build script MAKEP
2707/// - creates a LinkDef.h file
2708/// - runs rootcint generating demoProjectDict.cxx
2709/// - compiles demoProjectDict.cxx into demoProjectDict.o
2710/// - generates a shared lib demo.so
2711/// - dynamically links the shared lib demo.so to the executable
2712/// If only the option "+" had been specified, one can still link the
2713/// shared lib to the current executable module with:
2714///
2715/// gSystem->load("demo/demo.so");
2716///
2717/// The following feature is not yet enabled:
2718/// One can restrict the list of classes to be generated by using expressions like:
2719///
2720/// classes = "Ali*" generate code only for classes starting with Ali
2721/// classes = "myClass" generate code for class MyClass only.
2722///
2724void TFile::MakeProject(const char *dirname, const char * /*classes*/,
2726{
2727 TString opt = option;
2728 opt.ToLower();
2729 Bool_t makepar = kFALSE;
2730 TString parname, pardir;
2731 if (opt.Contains("par")) {
2732 // Create a PAR file
2733 parname = gSystem->BaseName(dirname);
2734 if (parname.EndsWith(".par")) parname.ReplaceAll(".par","");
2735 pardir = gSystem->GetDirName(dirname);
2736 // Cleanup or prepare the dirs
2737 TString path, filepath;
2738 void *dir = gSystem->OpenDirectory(pardir);
2739 if (dir) {
2740 path.Form("%s/%s", pardir.Data(), parname.Data());
2741 void *dirp = gSystem->OpenDirectory(path);
2742 if (dirp) {
2743 path += "/PROOF-INF";
2744 void *dirinf = gSystem->OpenDirectory(path);
2745 const char *afile = 0;
2746 if (dirinf) {
2747 while ((afile = gSystem->GetDirEntry(dirinf))) {
2748 if (strcmp(afile,".") == 0) continue;
2749 if (strcmp(afile,"..") == 0) continue;
2750 filepath.Form("%s/%s", path.Data(), afile);
2751 if (gSystem->Unlink(filepath))
2752 Warning("MakeProject", "1: problems unlinking '%s' ('%s', '%s')", filepath.Data(), path.Data(), afile);
2753 }
2754 gSystem->FreeDirectory(dirinf);
2755 }
2756 gSystem->Unlink(path);
2757 path.Form("%s/%s", pardir.Data(), parname.Data());
2758 while ((afile = gSystem->GetDirEntry(dirp))) {
2759 if (strcmp(afile,".") == 0) continue;
2760 if (strcmp(afile,"..") == 0) continue;
2761 filepath.Form("%s/%s", path.Data(), afile);
2762 if (gSystem->Unlink(filepath))
2763 Warning("MakeProject", "2: problems unlinking '%s' ('%s', '%s')", filepath.Data(), path.Data(), afile);
2764 }
2765 gSystem->FreeDirectory(dirp);
2766 if (gSystem->Unlink(path))
2767 Warning("MakeProject", "problems unlinking '%s'", path.Data());
2768 }
2769 }
2770 // Make sure that the relevant dirs exists: this is mandatory, so we fail if unsuccessful
2771 path.Form("%s/%s/PROOF-INF", pardir.Data(), parname.Data());
2772 if (gSystem->mkdir(path, kTRUE)) {
2773 Error("MakeProject", "problems creating '%s'", path.Data());
2774 return;
2775 }
2776 makepar = kTRUE;
2777
2778 } else {
2779 void *dir = gSystem->OpenDirectory(dirname);
2780 TString dirpath;
2781
2782 if (opt.Contains("update")) {
2783 // check that directory exist, if not create it
2784 if (!dir) {
2785 gSystem->mkdir(dirname);
2786 }
2787
2788 } else if (opt.Contains("recreate")) {
2789 // check that directory exist, if not create it
2790 if (!dir) {
2791 if (gSystem->mkdir(dirname) < 0) {
2792 Error("MakeProject","cannot create directory '%s'",dirname);
2793 return;
2794 }
2795 }
2796 // clear directory
2797 while (dir) {
2798 const char *afile = gSystem->GetDirEntry(dir);
2799 if (!afile) break;
2800 if (strcmp(afile,".") == 0) continue;
2801 if (strcmp(afile,"..") == 0) continue;
2802 dirpath.Form("%s/%s",dirname,afile);
2803 gSystem->Unlink(dirpath);
2804 }
2805
2806 } else {
2807 // new is assumed
2808 // if directory already exist, print error message and return
2809 if (dir) {
2810 Error("MakeProject","cannot create directory %s, already existing",dirname);
2811 gSystem->FreeDirectory(dir);
2812 return;
2813 }
2814 if (gSystem->mkdir(dirname) < 0) {
2815 Error("MakeProject","cannot create directory '%s'",dirname);
2816 return;
2817 }
2818 }
2819 if (dir) {
2820 gSystem->FreeDirectory(dir);
2821 }
2822 }
2823 Bool_t genreflex = opt.Contains("genreflex");
2824
2825 // we are now ready to generate the classes
2826 // loop on all TStreamerInfo
2827 TList *filelist = (TList*)GetStreamerInfoCache();
2828 if (filelist) filelist = (TList*)filelist->Clone();
2829 if (!filelist) {
2830 Error("MakeProject","file %s has no StreamerInfo", GetName());
2831 return;
2832 }
2833
2834 TString clean_dirname(dirname);
2835 if (makepar) clean_dirname.Form("%s/%s", pardir.Data(), parname.Data());
2836 if (clean_dirname[clean_dirname.Length()-1]=='/') {
2837 clean_dirname.Remove(clean_dirname.Length()-1);
2838 } else if (clean_dirname[clean_dirname.Length()-1]=='\\') {
2839 clean_dirname.Remove(clean_dirname.Length()-1);
2840 if (clean_dirname[clean_dirname.Length()-1]=='\\') {
2841 clean_dirname.Remove(clean_dirname.Length()-1);
2842 }
2843 }
2844 TString subdirname( gSystem->BaseName(clean_dirname) );
2845 if (makepar) subdirname = parname;
2846 if (subdirname == "") {
2847 Error("MakeProject","Directory name must not be empty.");
2848 return;
2849 }
2850
2851 // Start the source file
2852 TString spath; spath.Form("%s/%sProjectSource.cxx",clean_dirname.Data(),subdirname.Data());
2853 FILE *sfp = fopen(spath.Data(),"w");
2854 if (!sfp) {
2855 Error("MakeProject","Unable to create the source file %s.",spath.Data());
2856 return;
2857 }
2858 fprintf(sfp, "namespace std {}\nusing namespace std;\n");
2859 fprintf(sfp, "#include \"%sProjectHeaders.h\"\n\n",subdirname.Data() );
2860 if (!genreflex) fprintf(sfp, "#include \"%sLinkDef.h\"\n\n",subdirname.Data() );
2861 fprintf(sfp, "#include \"%sProjectDict.cxx\"\n\n",subdirname.Data() );
2862 fprintf(sfp, "struct DeleteObjectFunctor {\n");
2863 fprintf(sfp, " template <typename T>\n");
2864 fprintf(sfp, " void operator()(const T *ptr) const {\n");
2865 fprintf(sfp, " delete ptr;\n");
2866 fprintf(sfp, " }\n");
2867 fprintf(sfp, " template <typename T, typename Q>\n");
2868 fprintf(sfp, " void operator()(const std::pair<T,Q> &) const {\n");
2869 fprintf(sfp, " // Do nothing\n");
2870 fprintf(sfp, " }\n");
2871 fprintf(sfp, " template <typename T, typename Q>\n");
2872 fprintf(sfp, " void operator()(const std::pair<T,Q*> &ptr) const {\n");
2873 fprintf(sfp, " delete ptr.second;\n");
2874 fprintf(sfp, " }\n");
2875 fprintf(sfp, " template <typename T, typename Q>\n");
2876 fprintf(sfp, " void operator()(const std::pair<T*,Q> &ptr) const {\n");
2877 fprintf(sfp, " delete ptr.first;\n");
2878 fprintf(sfp, " }\n");
2879 fprintf(sfp, " template <typename T, typename Q>\n");
2880 fprintf(sfp, " void operator()(const std::pair<T*,Q*> &ptr) const {\n");
2881 fprintf(sfp, " delete ptr.first;\n");
2882 fprintf(sfp, " delete ptr.second;\n");
2883 fprintf(sfp, " }\n");
2884 fprintf(sfp, "};\n\n");
2885 fclose( sfp );
2886
2887 // loop on all TStreamerInfo classes to check for empty classes
2888 // and enums listed either as data member or template parameters,
2889 // and filter out 'duplicates' classes/streamerInfos.
2890 TStreamerInfo *info;
2891 TIter flnext(filelist);
2892 TList extrainfos;
2893 TList *list = new TList();
2894 while ((info = (TStreamerInfo*)flnext())) {
2895 if (info->IsA() != TStreamerInfo::Class()) {
2896 continue;
2897 }
2898 if (strstr(info->GetName(),"@@")) {
2899 // Skip schema evolution support streamerInfo
2900 continue;
2901 }
2902 TClass *cl = TClass::GetClass(info->GetName());
2903 if (cl) {
2904 if (cl->HasInterpreterInfo()) continue; // skip known classes
2905 }
2906 // Find and use the proper rules for the TStreamerInfos.
2908 TIter enext( info->GetElements() );
2909 TStreamerElement *el;
2911 if (cl && cl->GetSchemaRules()) {
2912 rules = cl->GetSchemaRules()->FindRules(cl->GetName(), info->GetClassVersion());
2913 }
2914 while( (el=(TStreamerElement*)enext()) ) {
2915 for(auto rule : rules) {
2916 if( rule->IsRenameRule() || rule->IsAliasRule() )
2917 continue;
2918 // Check whether this is an 'attribute' rule.
2919 if ( rule->HasTarget( el->GetName()) && rule->GetAttributes()[0] != 0 ) {
2920 TString attr( rule->GetAttributes() );
2921 attr.ToLower();
2922 if (attr.Contains("owner")) {
2923 if (attr.Contains("notowner")) {
2925 } else {
2927 }
2928 }
2929 }
2930 }
2932 }
2933 TVirtualStreamerInfo *alternate = (TVirtualStreamerInfo*)list->FindObject(info->GetName());
2934 if (alternate) {
2935 if ((info->GetClass() && info->GetClassVersion() == info->GetClass()->GetClassVersion())
2936 || (info->GetClassVersion() > alternate->GetClassVersion()) ) {
2937 list->AddAfter(alternate, info);
2938 list->Remove(alternate);
2939 } // otherwise ignore this info as not being the official one.
2940 } else {
2941 list->Add(info);
2942 }
2943 }
2944 // Now transfer the new StreamerInfo onto the main list and
2945 // to the owning list.
2946 TIter nextextra(&extrainfos);
2947 while ((info = (TStreamerInfo*)nextextra())) {
2948 list->Add(info);
2949 filelist->Add(info);
2950 }
2951
2952 // loop on all TStreamerInfo classes
2953 TIter next(list);
2954 Int_t ngener = 0;
2955 while ((info = (TStreamerInfo*)next())) {
2956 if (info->IsA() != TStreamerInfo::Class()) {
2957 continue;
2958 }
2959 if (info->GetClassVersion()==-4) continue; // Skip outer level namespace
2960 TIter subnext(list);
2961 TStreamerInfo *subinfo;
2962 TList subClasses;
2963 Int_t len = strlen(info->GetName());
2964 while ((subinfo = (TStreamerInfo*)subnext())) {
2965 if (subinfo->IsA() != TStreamerInfo::Class()) {
2966 continue;
2967 }
2968 if (strncmp(info->GetName(),subinfo->GetName(),len)==0) {
2969 // The 'sub' StreamerInfo start with the main StreamerInfo name,
2970 // it subinfo is likely to be a nested class.
2971 const Int_t sublen = strlen(subinfo->GetName());
2972 if ( (sublen > len) && subinfo->GetName()[len+1]==':'
2973 && !subClasses.FindObject(subinfo->GetName()) /* We need to insure uniqueness */)
2974 {
2975 subClasses.Add(subinfo);
2976 }
2977 }
2978 }
2979 ngener += info->GenerateHeaderFile(clean_dirname.Data(),&subClasses,&extrainfos);
2980 subClasses.Clear("nodelete");
2981 }
2982 extrainfos.Clear("nodelete"); // We are done with this list.
2983
2984 TString path;
2985 path.Form("%s/%sProjectHeaders.h",clean_dirname.Data(),subdirname.Data());
2986 FILE *allfp = fopen(path,"a");
2987 if (!allfp) {
2988 Error("MakeProject","Cannot open output file:%s\n",path.Data());
2989 } else {
2990 fprintf(allfp,"#include \"%sProjectInstances.h\"\n", subdirname.Data());
2991 fclose(allfp);
2992 }
2993
2994 printf("MakeProject has generated %d classes in %s\n",ngener,clean_dirname.Data());
2995
2996 // generate the shared lib
2997 if (!opt.Contains("+") && !makepar) {
2998 delete list;
2999 filelist->Delete();
3000 delete filelist;
3001 return;
3002 }
3003
3004 // Makefiles files
3005 FILE *fpMAKE = nullptr;
3006 if (!makepar) {
3007 // Create the MAKEP file by looping on all *.h files
3008 // delete MAKEP if it already exists
3009#ifdef WIN32
3010 path.Form("%s/makep.cmd",clean_dirname.Data());
3011#else
3012 path.Form("%s/MAKEP",clean_dirname.Data());
3013#endif
3014#ifdef R__WINGCC
3015 fpMAKE = fopen(path,"wb");
3016#else
3017 fpMAKE = fopen(path,"w");
3018#endif
3019 if (!fpMAKE) {
3020 Error("MakeProject", "cannot open file %s", path.Data());
3021 delete list;
3022 filelist->Delete();
3023 delete filelist;
3024 return;
3025 }
3026 }
3027
3028 // Add rootcint/genreflex statement generating ProjectDict.cxx
3029 FILE *ifp = nullptr;
3030 path.Form("%s/%sProjectInstances.h",clean_dirname.Data(),subdirname.Data());
3031#ifdef R__WINGCC
3032 ifp = fopen(path,"wb");
3033#else
3034 ifp = fopen(path,"w");
3035#endif
3036 if (!ifp) {
3037 Error("MakeProject", "cannot open path file %s", path.Data());
3038 delete list;
3039 filelist->Delete();
3040 delete filelist;
3041 fclose(fpMAKE);
3042 return;
3043 }
3044
3045 if (!makepar) {
3046 if (genreflex) {
3047 fprintf(fpMAKE,"genreflex %sProjectHeaders.h -o %sProjectDict.cxx --comments --iocomments %s ",subdirname.Data(),subdirname.Data(),gSystem->GetIncludePath());
3048 path.Form("%s/%sSelection.xml",clean_dirname.Data(),subdirname.Data());
3049 } else {
3050 fprintf(fpMAKE,"rootcint -v1 -f %sProjectDict.cxx %s ", subdirname.Data(), gSystem->GetIncludePath());
3051 path.Form("%s/%sLinkDef.h",clean_dirname.Data(),subdirname.Data());
3052 }
3053 } else {
3054 path.Form("%s/%sLinkDef.h",clean_dirname.Data(),subdirname.Data());
3055 }
3056
3057 // Create the LinkDef.h or xml selection file by looping on all *.h files
3058 // replace any existing file.
3059#ifdef R__WINGCC
3060 FILE *fp = fopen(path,"wb");
3061#else
3062 FILE *fp = fopen(path,"w");
3063#endif
3064 if (!fp) {
3065 Error("MakeProject", "cannot open path file %s", path.Data());
3066 delete list;
3067 filelist->Delete();
3068 delete filelist;
3069 fclose(fpMAKE);
3070 fclose(ifp);
3071 return;
3072 }
3073 if (genreflex) {
3074 fprintf(fp,"<lcgdict>\n");
3075 fprintf(fp,"\n");
3076 } else {
3077 fprintf(fp,"#ifdef __CINT__\n");
3078 fprintf(fp,"\n");
3079 }
3080
3081 TString tmp;
3082 TString instances;
3083 TString selections;
3084 next.Reset();
3085 while ((info = (TStreamerInfo*)next())) {
3086 if (info->IsA() != TStreamerInfo::Class()) {
3087 continue;
3088 }
3089 if (strncmp(info->GetName(), "auto_ptr<", std::char_traits<char>::length("auto_ptr<")) == 0) {
3090 continue;
3091 }
3092 TClass *cl = TClass::GetClass(info->GetName());
3093 if (cl) {
3094 if (cl->HasInterpreterInfo()) continue; // skip known classes
3095 if (cl->GetSchemaRules()) {
3096 auto rules = cl->GetSchemaRules()->FindRules(cl->GetName(), info->GetClassVersion());
3097 TString strrule;
3098 for(auto rule : rules) {
3099 strrule.Clear();
3100 if (genreflex) {
3101 rule->AsString(strrule,"x");
3102 strrule.Append("\n");
3103 if ( selections.Index(strrule) == kNPOS ) {
3104 selections.Append(strrule);
3105 }
3106 } else {
3107 rule->AsString(strrule);
3108 if (strncmp(strrule.Data(),"type=",5)==0) {
3109 strrule.Remove(0,5);
3110 }
3111 fprintf(fp,"#pragma %s;\n",strrule.Data());
3112 }
3113 }
3114 }
3115
3116 }
3117 if ((info->GetClass() && info->GetClass()->GetCollectionType()) || TClassEdit::IsSTLCont(info->GetName())) {
3118 std::vector<std::string> inside;
3119 int nestedLoc;
3120 TClassEdit::GetSplit( info->GetName(), inside, nestedLoc, TClassEdit::kLong64 );
3121 Int_t stlkind = TClassEdit::STLKind(inside[0]);
3122 TClass *key = TClass::GetClass(inside[1].c_str());
3123 if (key) {
3124 TString what;
3125 switch ( stlkind ) {
3126 case ROOT::kSTLmap:
3127 case ROOT::kSTLmultimap:
3128 if (TClass::GetClass(inside[1].c_str())) {
3129 what = "std::pair<";
3130 what += TMakeProject::UpdateAssociativeToVector( inside[1].c_str() );
3131 what += ",";
3132 what += TMakeProject::UpdateAssociativeToVector( inside[2].c_str() );
3133 if (what[what.Length()-1]=='>') {
3134 what += " >";
3135 } else {
3136 what += ">";
3137 }
3138 if (genreflex) {
3139 tmp.Form("<class name=\"%s\" />\n",what.Data());
3140 if ( selections.Index(tmp) == kNPOS ) {
3141 selections.Append(tmp);
3142 }
3143 tmp.Form("template class %s;\n",what.Data());
3144 if ( instances.Index(tmp) == kNPOS ) {
3145 instances.Append(tmp);
3146 }
3147 } else {
3148 what.ReplaceAll("std::","");
3149 TClass *paircl = TClass::GetClass(what.Data());
3150 if (!paircl || !paircl->HasInterpreterInfo()) {
3151 fprintf(fp,"#pragma link C++ class %s+;\n",what.Data());
3152 }
3153 }
3154 break;
3155 }
3156 default:
3157 if (TClassEdit::IsStdPair(key->GetName())) {
3158 if (genreflex) {
3159 tmp.Form("<class name=\"%s\" />\n",key->GetName());
3160 if ( selections.Index(tmp) == kNPOS ) {
3161 selections.Append(tmp);
3162 }
3163 tmp.Form("template class %s;\n",key->GetName());
3164 if ( instances.Index(tmp) == kNPOS ) {
3165 instances.Append(tmp);
3166 }
3167 } else {
3168 what.ReplaceAll("std::","");
3169 fprintf(fp,"#pragma link C++ class %s+;\n",key->GetName());
3170 }
3171 }
3172 break;
3173 }
3174 }
3175 continue;
3176 }
3177 {
3179 if (genreflex) {
3180 tmp.Form("<class name=\"%s\" />\n",what.Data());
3181 if ( selections.Index(tmp) == kNPOS ) {
3182 selections.Append(tmp);
3183 }
3184 if (what[what.Length()-1] == '>') {
3185 tmp.Form("template class %s;\n",what.Data());
3186 if ( instances.Index(tmp) == kNPOS ) {
3187 instances.Append(tmp);
3188 }
3189 }
3190 } else {
3191 what.ReplaceAll("std::","");
3192 fprintf(fp,"#pragma link C++ class %s+;\n",what.Data());
3193 }
3194 }
3195 if (genreflex) {
3196 // Also request the dictionary for the STL container used as members ...
3197 TIter eliter( info->GetElements() );
3198 TStreamerElement *element;
3199 while( (element = (TStreamerElement*)eliter() ) ) {
3200 if (element->GetClass() && !element->GetClass()->IsLoaded() && element->GetClass()->GetCollectionProxy()) {
3202 tmp.Form("<class name=\"%s\" />\n",what.Data());
3203 if ( selections.Index(tmp) == kNPOS ) {
3204 selections.Append(tmp);
3205 }
3206 tmp.Form("template class %s;\n",what.Data());
3207 if ( instances.Index(tmp) == kNPOS ) {
3208 instances.Append(tmp);
3209 }
3210 }
3211 }
3212 }
3213 }
3214 if (genreflex) {
3215 fprintf(ifp,"#ifndef PROJECT_INSTANCES_H\n");
3216 fprintf(ifp,"#define PROJECT_INSTANCES_H\n");
3217 fprintf(ifp,"%s",instances.Data());
3218 fprintf(ifp,"#endif\n");
3219 fprintf(fp,"%s",selections.Data());
3220 fprintf(fp,"</lcgdict>\n");
3221 } else {
3222 fprintf(fp,"#endif\n");
3223 }
3224 fclose(fp);
3225 fclose(ifp);
3226
3227 if (!makepar) {
3228 // add compilation line
3229 TString sdirname(subdirname);
3230
3232 TString sources = TString::Format("%sProjectSource.cxx ", sdirname.Data());
3233 cmd.ReplaceAll("$SourceFiles",sources.Data());
3234 TString object = TString::Format("%sProjectSource.", sdirname.Data());
3235 object.Append( gSystem->GetObjExt() );
3236 cmd.ReplaceAll("$ObjectFiles", object.Data());
3237 cmd.ReplaceAll("$IncludePath",TString(gSystem->GetIncludePath()) + " -I" + clean_dirname.Data());
3238 cmd.ReplaceAll("$SharedLib",sdirname+"."+gSystem->GetSoExt());
3239 cmd.ReplaceAll("$LinkedLibs",gSystem->GetLibraries("","SDL"));
3240 cmd.ReplaceAll("$LibName",sdirname);
3241 cmd.ReplaceAll("$BuildDir",".");
3242 TString sOpt;
3243 TString rootbuild = ROOTBUILD;
3244 if (rootbuild.Index("debug",0,TString::kIgnoreCase)==kNPOS) {
3245 sOpt = gSystem->GetFlagsOpt();
3246 } else {
3247 sOpt = gSystem->GetFlagsDebug();
3248 }
3249 cmd.ReplaceAll("$Opt", sOpt);
3250
3251 if (genreflex) {
3252 fprintf(fpMAKE,"-s %sSelection.xml \n",subdirname.Data());
3253 } else {
3254 fprintf(fpMAKE,"%sProjectHeaders.h ",subdirname.Data());
3255 fprintf(fpMAKE,"%sLinkDef.h \n",subdirname.Data());
3256 }
3257
3258 fprintf(fpMAKE,"%s\n",cmd.Data());
3259
3260 printf("%s/MAKEP file has been generated\n", clean_dirname.Data());
3261
3262 fclose(fpMAKE);
3263
3264 } else {
3265
3266 // Create the Makefile
3267 TString filemake = TString::Format("%s/Makefile", clean_dirname.Data());
3268 if (MakeProjectParMake(parname, filemake.Data()) != 0) {
3269 Error("MakeProject", "problems creating PAR make file '%s'", filemake.Data());
3270 delete list;
3271 filelist->Delete();
3272 delete filelist;
3273 return;
3274 }
3275 // Get Makefile.arch
3276 TString mkarchsrc = TString::Format("%s/Makefile.arch", TROOT::GetEtcDir().Data());
3277 if (gSystem->ExpandPathName(mkarchsrc))
3278 Warning("MakeProject", "problems expanding '%s'", mkarchsrc.Data());
3279 TString mkarchdst = TString::Format("%s/Makefile.arch", clean_dirname.Data());
3280 if (gSystem->CopyFile(mkarchsrc.Data(), mkarchdst.Data(), kTRUE) != 0) {
3281 Error("MakeProject", "problems retrieving '%s' to '%s'", mkarchsrc.Data(), mkarchdst.Data());
3282 delete list;
3283 filelist->Delete();
3284 delete filelist;
3285 return;
3286 }
3287 // Create the Makefile
3288 TString proofinf = TString::Format("%s/PROOF-INF", clean_dirname.Data());
3289 if (MakeProjectParProofInf(parname, proofinf.Data()) != 0) {
3290 Error("MakeProject", "problems creating BUILD.sh and/or SETUP.C under '%s'", proofinf.Data());
3291 delete list;
3292 filelist->Delete();
3293 delete filelist;
3294 return;
3295 }
3296
3297 // Make sure BUILD.sh is executable and create SETUP.C
3298 TString cmod = TString::Format("chmod +x %s/PROOF-INF/BUILD.sh", clean_dirname.Data());
3299#ifndef WIN32
3300 gSystem->Exec(cmod.Data());
3301#else
3302 // not really needed for Windows but it would work both both Unix and NT
3303 chmod(cmod.Data(), 00700);
3304#endif
3305 Printf("Files Makefile, Makefile.arch, PROOF-INF/BUILD.sh and"
3306 " PROOF-INF/SETUP.C have been generated under '%s'", clean_dirname.Data());
3307
3308 // Generate the PAR file, if not Windows
3309#ifndef WIN32
3310 TString curdir = gSystem->WorkingDirectory();
3311 if (gSystem->ChangeDirectory(pardir)) {
3312 TString cmd = TString::Format("tar czvf %s.par %s", parname.Data(), parname.Data());
3313 gSystem->Exec(cmd.Data());
3314 if (gSystem->ChangeDirectory(curdir)) {
3315 Info("MakeProject", "PAR file %s.par generated", clean_dirname.Data());
3316 } else {
3317 Warning("MakeProject", "problems changing directory back to '%s'", curdir.Data());
3318 }
3319 } else {
3320 Error("MakeProject", "problems changing directory to '%s' - skipping PAR file generation", pardir.Data());
3321 }
3322#else
3323 Warning("MakeProject", "on Windows systems the PAR file cannot be generated out of the package directory!");
3324#endif
3325 }
3326
3327
3328 if (!makepar && !opt.Contains("nocompilation")) {
3329 // now execute the generated script compiling and generating the shared lib
3330 path = gSystem->WorkingDirectory();
3331 gSystem->ChangeDirectory(clean_dirname.Data());
3332#ifndef WIN32
3333 gSystem->Exec("chmod +x MAKEP");
3334 int res = !gSystem->Exec("./MAKEP");
3335#else
3336 // not really needed for Windows but it would work both both Unix and NT
3337 chmod("makep.cmd",00700);
3338 int res = !gSystem->Exec("MAKEP");
3339#endif
3340 gSystem->ChangeDirectory(path);
3341 path.Form("%s/%s.%s",clean_dirname.Data(),subdirname.Data(),gSystem->GetSoExt());
3342 if (res) printf("Shared lib %s has been generated\n",path.Data());
3343
3344 //dynamically link the generated shared lib
3345 if (opt.Contains("++")) {
3346 res = !gSystem->Load(path);
3347 if (res) printf("Shared lib %s has been dynamically linked\n",path.Data());
3348 }
3349 }
3350
3351 delete list;
3352 filelist->Delete();
3353 delete filelist;
3354}
3355
3356////////////////////////////////////////////////////////////////////////////////
3357/// Create makefile at 'filemake' for PAR package 'pack'.
3358///
3359/// Called by MakeProject when option 'par' is given.
3360/// Return 0 on success, -1 on error.
3362Int_t TFile::MakeProjectParMake(const char *pack, const char *filemake)
3363{
3364 // Output file path must be defined
3365 if (!filemake || (filemake && strlen(filemake) <= 0)) {
3366 Error("MakeProjectParMake", "path for output file undefined!");
3367 return -1;
3368 }
3369
3370 // Package name must be defined
3371 if (!pack || (pack && strlen(pack) <= 0)) {
3372 Error("MakeProjectParMake", "package name undefined!");
3373 return -1;
3374 }
3375
3376#ifdef R__WINGCC
3377 FILE *fmk = fopen(filemake, "wb");
3378#else
3379 FILE *fmk = fopen(filemake, "w");
3380#endif
3381 if (!fmk) {
3382 Error("MakeProjectParMake", "cannot create file '%s' (errno: %d)", filemake, TSystem::GetErrno());
3383 return -1;
3384 }
3385
3386 // Fill the file now
3387 fprintf(fmk, "# Makefile for the ROOT test programs.\n");
3388 fprintf(fmk, "# This Makefile shows how to compile and link applications\n");
3389 fprintf(fmk, "# using the ROOT libraries on all supported platforms.\n");
3390 fprintf(fmk, "#\n");
3391 fprintf(fmk, "# Copyright (c) 2000 Rene Brun and Fons Rademakers\n");
3392 fprintf(fmk, "#\n");
3393 fprintf(fmk, "# Author: this makefile has been automatically generated via TFile::MakeProject\n");
3394 fprintf(fmk, "\n");
3395 fprintf(fmk, "include Makefile.arch\n");
3396 fprintf(fmk, "\n");
3397 fprintf(fmk, "#------------------------------------------------------------------------------\n");
3398 fprintf(fmk, "\n");
3399 fprintf(fmk, "PACKO = %sProjectSource.$(ObjSuf)\n", pack);
3400 fprintf(fmk, "PACKS = %sProjectSource.$(SrcSuf) %sProjectDict.$(SrcSuf)\n", pack, pack);
3401 fprintf(fmk, "PACKSO = lib%s.$(DllSuf)\n", pack);
3402 fprintf(fmk, "\n");
3403 fprintf(fmk, "ifeq ($(PLATFORM),win32)\n");
3404 fprintf(fmk, "PACKLIB = lib%s.lib\n", pack);
3405 fprintf(fmk, "else\n");
3406 fprintf(fmk, "PACKLIB = $(PACKSO)\n");
3407 fprintf(fmk, "endif\n");
3408 fprintf(fmk, "\n");
3409 fprintf(fmk, "OBJS = $(PACKO)\n");
3410 fprintf(fmk, "\n");
3411 fprintf(fmk, "PROGRAMS =\n");
3412 fprintf(fmk, "\n");
3413 fprintf(fmk, "#------------------------------------------------------------------------------\n");
3414 fprintf(fmk, "\n");
3415 fprintf(fmk, ".SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf)\n");
3416 fprintf(fmk, "\n");
3417 fprintf(fmk, "all: $(PACKLIB)\n");
3418 fprintf(fmk, "\n");
3419 fprintf(fmk, "$(PACKSO): $(PACKO)\n");
3420 fprintf(fmk, "ifeq ($(ARCH),aix)\n");
3421 fprintf(fmk, "\t\t/usr/ibmcxx/bin/makeC++SharedLib $(OutPutOpt) $@ $(LIBS) -p 0 $^\n");
3422 fprintf(fmk, "else\n");
3423 fprintf(fmk, "ifeq ($(ARCH),aix5)\n");
3424 fprintf(fmk, "\t\t/usr/vacpp/bin/makeC++SharedLib $(OutPutOpt) $@ $(LIBS) -p 0 $^\n");
3425 fprintf(fmk, "else\n");
3426 fprintf(fmk, "ifeq ($(PLATFORM),macosx)\n");
3427 fprintf(fmk, "# We need to make both the .dylib and the .so\n");
3428 fprintf(fmk, "\t\t$(LD) $(SOFLAGS)$@ $(LDFLAGS) $^ $(OutPutOpt) $@ $(LIBS)\n");
3429 fprintf(fmk, "ifneq ($(subst $(MACOSX_MINOR),,1234),1234)\n");
3430 fprintf(fmk, "ifeq ($(MACOSX_MINOR),4)\n");
3431 fprintf(fmk, "\t\tln -sf $@ $(subst .$(DllSuf),.so,$@)\n");
3432 fprintf(fmk, "else\n");
3433 fprintf(fmk, "\t\t$(LD) -bundle -undefined $(UNDEFOPT) $(LDFLAGS) $^ \\\n");
3434 fprintf(fmk, "\t\t $(OutPutOpt) $(subst .$(DllSuf),.so,$@)\n");
3435 fprintf(fmk, "endif\n");
3436 fprintf(fmk, "endif\n");
3437 fprintf(fmk, "else\n");
3438 fprintf(fmk, "ifeq ($(PLATFORM),win32)\n");
3439 fprintf(fmk, "\t\tbindexplib $* $^ > $*.def\n");
3440 fprintf(fmk, "\t\tlib -nologo -MACHINE:IX86 $^ -def:$*.def \\\n");
3441 fprintf(fmk, "\t\t $(OutPutOpt)$(PACKLIB)\n");
3442 fprintf(fmk, "\t\t$(LD) $(SOFLAGS) $(LDFLAGS) $^ $*.exp $(LIBS) \\\n");
3443 fprintf(fmk, "\t\t $(OutPutOpt)$@\n");
3444 fprintf(fmk, "else\n");
3445 fprintf(fmk, "\t\t$(LD) $(SOFLAGS) $(LDFLAGS) $^ $(OutPutOpt) $@ $(LIBS) $(EXPLLINKLIBS)\n");
3446 fprintf(fmk, "endif\n");
3447 fprintf(fmk, "endif\n");
3448 fprintf(fmk, "endif\n");
3449 fprintf(fmk, "endif\n");
3450 fprintf(fmk, "\t\t@echo \"$@ done\"\n");
3451 fprintf(fmk, "\n");
3452 fprintf(fmk, "clean:\n");
3453 fprintf(fmk, "\t\t@rm -f $(OBJS) core\n");
3454 fprintf(fmk, "\n");
3455 fprintf(fmk, "distclean: clean\n");
3456 fprintf(fmk, "\t\t@rm -f $(PROGRAMS) $(PACKSO) $(PACKLIB) *Dict.* *.def *.exp \\\n");
3457 fprintf(fmk, "\t\t *.so *.lib *.dll *.d *.log .def so_locations\n");
3458 fprintf(fmk, "\t\t@rm -rf cxx_repository\n");
3459 fprintf(fmk, "\n");
3460 fprintf(fmk, "# Dependencies\n");
3461 fprintf(fmk, "\n");
3462 fprintf(fmk, "%sProjectSource.$(ObjSuf): %sProjectHeaders.h %sLinkDef.h %sProjectDict.$(SrcSuf)\n", pack, pack, pack, pack);
3463 fprintf(fmk, "\n");
3464 fprintf(fmk, "%sProjectDict.$(SrcSuf): %sProjectHeaders.h %sLinkDef.h\n", pack, pack, pack);
3465 fprintf(fmk, "\t\t@echo \"Generating dictionary $@...\"\n");
3466 fprintf(fmk, "\t\t@rootcint -f $@ $^\n");
3467 fprintf(fmk, "\n");
3468 fprintf(fmk, ".$(SrcSuf).$(ObjSuf):\n");
3469 fprintf(fmk, "\t\t$(CXX) $(CXXFLAGS) -c $<\n");
3470 fprintf(fmk, "\n");
3471
3472 // Close the file
3473 fclose(fmk);
3474
3475 // Done
3476 return 0;
3477}
3478
3479////////////////////////////////////////////////////////////////////////////////
3480/// Create BUILD.sh and SETUP.C under 'proofinf' for PAR package 'pack'.
3481/// Called by MakeProject when option 'par' is given.
3482/// Return 0 on success, -1 on error.
3484Int_t TFile::MakeProjectParProofInf(const char *pack, const char *proofinf)
3485{
3486 // Output directory path must be defined ...
3487 if (!proofinf || (proofinf && strlen(proofinf) <= 0)) {
3488 Error("MakeProjectParProofInf", "directory path undefined!");
3489 return -1;
3490 }
3491
3492 // ... and exist and be a directory
3493 Int_t rcst = 0;
3494 FileStat_t st;
3495 if ((rcst = gSystem->GetPathInfo(proofinf, st)) != 0 || !R_ISDIR(st.fMode)) {
3496 Error("MakeProjectParProofInf", "path '%s' %s", proofinf,
3497 ((rcst == 0) ? "is not a directory" : "does not exist"));
3498 return -1;
3499 }
3500
3501 // Package name must be defined
3502 if (!pack || (pack && strlen(pack) <= 0)) {
3503 Error("MakeProjectParProofInf", "package name undefined!");
3504 return -1;
3505 }
3506
3507 TString path;
3508
3509 // The BUILD.sh first
3510 path.Form("%s/BUILD.sh", proofinf);
3511#ifdef R__WINGCC
3512 FILE *f = fopen(path.Data(), "wb");
3513#else
3514 FILE *f = fopen(path.Data(), "w");
3515#endif
3516 if (!f) {
3517 Error("MakeProjectParProofInf", "cannot create file '%s' (errno: %d)",
3518 path.Data(), TSystem::GetErrno());
3519 return -1;
3520 }
3521
3522 fprintf(f, "#! /bin/sh\n");
3523 fprintf(f, "# Build libEvent library.\n");
3524 fprintf(f, "\n");
3525 fprintf(f, "#\n");
3526 fprintf(f, "# The environment variables ROOTPROOFLITE and ROOTPROOFCLIENT can be used to\n");
3527 fprintf(f, "# adapt the script to the calling environment\n");
3528 fprintf(f, "#\n");
3529 fprintf(f, "# if test ! \"x$ROOTPROOFLITE\" = \"x\"; then\n");
3530 fprintf(f, "# echo \"event-BUILD: PROOF-Lite node (session has $ROOTPROOFLITE workers)\"\n");
3531 fprintf(f, "# elif test ! \"x$ROOTPROOFCLIENT\" = \"x\"; then\n");
3532 fprintf(f, "# echo \"event-BUILD: PROOF client\"\n");
3533 fprintf(f, "# else\n");
3534 fprintf(f, "# echo \"event-BUILD: standard PROOF node\"\n");
3535 fprintf(f, "# fi\n");
3536 fprintf(f, "\n");
3537 fprintf(f, "if [ \"\" = \"clean\" ]; then\n");
3538 fprintf(f, " make distclean\n");
3539 fprintf(f, " exit 0\n");
3540 fprintf(f, "fi\n");
3541 fprintf(f, "\n");
3542 fprintf(f, "make\n");
3543 fprintf(f, "rc=$?\n");
3544 fprintf(f, "echo \"rc=$?\"\n");
3545 fprintf(f, "if [ $? != \"0\" ] ; then\n");
3546 fprintf(f, " exit 1\n");
3547 fprintf(f, "fi\n");
3548 fprintf(f, "exit 0\n");
3549
3550 // Close the file
3551 fclose(f);
3552
3553 // Then SETUP.C
3554 path.Form("%s/SETUP.C", proofinf);
3555#ifdef R__WINGCC
3556 f = fopen(path.Data(), "wb");
3557#else
3558 f = fopen(path.Data(), "w");
3559#endif
3560 if (!f) {
3561 Error("MakeProjectParProofInf", "cannot create file '%s' (errno: %d)",
3562 path.Data(), TSystem::GetErrno());
3563 return -1;
3564 }
3565
3566 fprintf(f, "Int_t SETUP()\n");
3567 fprintf(f, "{\n");
3568 fprintf(f, "\n");
3569 fprintf(f, "//\n");
3570 fprintf(f, "// The environment variables ROOTPROOFLITE and ROOTPROOFCLIENT can be used to\n");
3571 fprintf(f, "// adapt the macro to the calling environment\n");
3572 fprintf(f, "//\n");
3573 fprintf(f, "// if (gSystem->Getenv(\"ROOTPROOFLITE\")) {\n");
3574 fprintf(f, "// Printf(\"event-SETUP: PROOF-Lite node (session has %%s workers)\",\n");
3575 fprintf(f, "// gSystem->Getenv(\"ROOTPROOFLITE\"));\n");
3576 fprintf(f, "// } else if (gSystem->Getenv(\"ROOTPROOFCLIENT\")) {\n");
3577 fprintf(f, "// Printf(\"event-SETUP: PROOF client\");\n");
3578 fprintf(f, "// } else {\n");
3579 fprintf(f, "// Printf(\"event-SETUP: standard PROOF node\");\n");
3580 fprintf(f, "// }\n");
3581 fprintf(f, "\n");
3582 fprintf(f, " if (gSystem->Load(\"lib%s\") == -1)\n", pack);
3583 fprintf(f, " return -1;\n");
3584 fprintf(f, " return 0;\n");
3585 fprintf(f, "}\n");
3586 fprintf(f, "\n");
3587
3588 // Close the file
3589 fclose(f);
3590
3591 // Done
3592 return 0;
3593}
3594
3595////////////////////////////////////////////////////////////////////////////////
3596/// Read the list of StreamerInfo from this file.
3597///
3598/// The key with name holding the list of TStreamerInfo objects is read.
3599/// The corresponding TClass objects are updated.
3600/// Note that this function is not called if the static member fgReadInfo is false.
3601/// (see TFile::SetReadStreamerInfo)
3604{
3605 auto listRetcode = GetStreamerInfoListImpl(/*lookupSICache*/ true); // NOLINT: silence clang-tidy warnings
3606 TList *list = listRetcode.fList;
3607 auto retcode = listRetcode.fReturnCode;
3608 if (!list) {
3609 if (retcode) MakeZombie();
3610 return;
3611 }
3612
3613 list->SetOwner(kFALSE);
3614
3615 if (gDebug > 0) Info("ReadStreamerInfo", "called for file %s",GetName());
3616
3617 TStreamerInfo *info;
3618
3619 Int_t version = fVersion;
3620 if (version > 1000000) version -= 1000000;
3621 if (version < 53419 || (59900 < version && version < 59907)) {
3622 // We need to update the fCheckSum field of the TStreamerBase.
3623
3624 // loop on all TStreamerInfo classes
3625 TObjLink *lnk = list->FirstLink();
3626 while (lnk) {
3627 info = (TStreamerInfo*)lnk->GetObject();
3628 if (!info || info->IsA() != TStreamerInfo::Class()) {
3629 lnk = lnk->Next();
3630 continue;
3631 }
3632 TIter next(info->GetElements());
3633 TStreamerElement *element;
3634 while ((element = (TStreamerElement*) next())) {
3635 TStreamerBase *base = dynamic_cast<TStreamerBase*>(element);
3636 if (!base) continue;
3637 if (base->GetBaseCheckSum() != 0) continue;
3638 TStreamerInfo *baseinfo = (TStreamerInfo*)list->FindObject(base->GetName());
3639 if (baseinfo) {
3640 base->SetBaseCheckSum(baseinfo->GetCheckSum());
3641 }
3642 }
3643 lnk = lnk->Next();
3644 }
3645 }
3646
3647 std::vector<Int_t> si_uids;
3648 // loop on all TStreamerInfo classes
3649 for (int mode=0;mode<2; ++mode) {
3650 // In order for the collection proxy to be initialized properly, we need
3651 // to setup the TStreamerInfo for non-stl class before the stl classes.
3652 TObjLink *lnk = list->FirstLink();
3653 while (lnk) {
3654 info = (TStreamerInfo*)lnk->GetObject();
3655 if (!info) {
3656 lnk = lnk->Next();
3657 continue;
3658 }
3659 if (info->IsA() != TStreamerInfo::Class()) {
3660 if (mode==1) {
3661 TObject *obj = (TObject*)info;
3662 if (strcmp(obj->GetName(),"listOfRules")==0) {
3663#if 0
3664 // Completely ignore the rules for now.
3665 TList *listOfRules = (TList*)obj;
3666 TObjLink *rulelnk = listOfRules->FirstLink();
3667 while (rulelnk) {
3668 TObjString *rule = (TObjString*)rulelnk->GetObject();
3669 TClass::AddRule( rule->String().Data() );
3670 rulelnk = rulelnk->Next();
3671 }
3672#endif
3673 } else {
3674 Warning("ReadStreamerInfo","%s has a %s in the list of TStreamerInfo.", GetName(), info->IsA()->GetName());
3675 }
3676 info->SetBit(kCanDelete);
3677 }
3678 lnk = lnk->Next();
3679 continue;
3680 }
3681 // This is a quick way (instead of parsing the name) to see if this is
3682 // the description of an STL container.
3683 if (info->GetElements()==0) {
3684 Warning("ReadStreamerInfo","The StreamerInfo for %s does not have a list of elements.",info->GetName());
3685 lnk = lnk->Next();
3686 continue;
3687 }
3688 TObject *element = info->GetElements()->UncheckedAt(0);
3689 Bool_t isstl = element && strcmp("This",element->GetName())==0;
3690
3691 if ( (!isstl && mode ==0) || (isstl && mode ==1) ) {
3692 // Skip the STL container the first time around
3693 // Skip the regular classes the second time around;
3694 info->BuildCheck(this);
3695 Int_t uid = info->GetNumber();
3696 Int_t asize = fClassIndex->GetSize();
3697 if (uid >= asize && uid <100000) fClassIndex->Set(2*asize);
3698 if (uid >= 0 && uid < fClassIndex->GetSize()) {
3699 si_uids.push_back(uid);
3700 fClassIndex->fArray[uid] = 1;
3701 }
3702 else if (!isstl && !info->GetClass()->IsSyntheticPair()) {
3703 printf("ReadStreamerInfo, class:%s, illegal uid=%d\n",info->GetName(),uid);
3704 }
3705 if (gDebug > 0) printf(" -class: %s version: %d info read at slot %d\n",info->GetName(), info->GetClassVersion(),uid);
3706 }
3707 lnk = lnk->Next();
3708 }
3709 }
3710 fClassIndex->fArray[0] = 0;
3711 list->Clear(); //this will delete all TStreamerInfo objects with kCanDelete bit set
3712 delete list;
3713
3714 // We are done processing the record, let future calls and other threads that it
3715 // has been done.
3716 fgTsSIHashes.Insert(listRetcode.fHash, std::move(si_uids));
3717}
3718
3719////////////////////////////////////////////////////////////////////////////////
3720/// Specify if the streamerinfos must be read at file opening.
3721///
3722/// If fgReadInfo is true (default) TFile::ReadStreamerInfo is called
3723/// when opening the file.
3724/// It may be interesting to set fgReadInfo to false to speedup the file
3725/// opening time or in case libraries containing classes referenced
3726/// by the file have not yet been loaded.
3727/// if fgReadInfo is false, one can still read the StreamerInfo with
3728/// myfile.ReadStreamerInfo();
3731{
3732 fgReadInfo = readinfo;
3733}
3734
3735////////////////////////////////////////////////////////////////////////////////
3736/// If the streamerinfos are to be read at file opening.
3737///
3738/// See TFile::SetReadStreamerInfo for more documentation.
3741{
3742 return fgReadInfo;
3743}
3744
3745////////////////////////////////////////////////////////////////////////////////
3746/// Show the StreamerInfo of all classes written to this file.
3749{
3750 TList *list = GetStreamerInfoList();
3751 if (!list) return;
3752
3753 list->ls();
3754 delete list;
3755}
3756
3757////////////////////////////////////////////////////////////////////////////////
3758/// Check if the ProcessID pidd is already in the file,
3759/// if not, add it and return the index number in the local file list.
3762{
3763 TProcessID *pid = pidd;
3764 if (!pid) pid = TProcessID::GetPID();
3766 Int_t npids = GetNProcessIDs();
3767 for (Int_t i=0;i<npids;i++) {
3768 if (pids->At(i) == pid) return (UShort_t)i;
3769 }
3770
3772 pids->AddAtAndExpand(pid,npids);
3773 pid->IncrementCount();
3774 char name[32];
3775 snprintf(name,32,"ProcessID%d",npids);
3776 this->WriteTObject(pid,name);
3777 this->IncrementProcessIDs();
3778 if (gDebug > 0) {
3779 Info("WriteProcessID", "name=%s, file=%s", name, GetName());
3780 }
3781 return (UShort_t)npids;
3782}
3783
3784
3785////////////////////////////////////////////////////////////////////////////////
3786/// Write the list of TStreamerInfo as a single object in this file
3787/// The class Streamer description for all classes written to this file
3788/// is saved. See class TStreamerInfo.
3791{
3792 //if (!gFile) return;
3793 if (!fWritable) return;
3794 if (!fClassIndex) return;
3795 if (fIsPcmFile) return; // No schema evolution for ROOT PCM files.
3796 if (fClassIndex->fArray[0] == 0
3797 && fSeekInfo != 0) {
3798 // No need to update the index if no new classes added to the file
3799 // but write once an empty StreamerInfo list to mark that there is no need
3800 // for StreamerInfos in this file.
3801 return;
3802 }
3803 if (gDebug > 0) Info("WriteStreamerInfo", "called for file %s",GetName());
3804
3806
3807 // build a temporary list with the marked files
3808 TIter next(gROOT->GetListOfStreamerInfo());
3809 TStreamerInfo *info;
3810 TList list;
3811 TList listOfRules;
3812 listOfRules.SetOwner(kTRUE);
3813 listOfRules.SetName("listOfRules");
3814 std::set<TClass*> classSet;
3815
3816 while ((info = (TStreamerInfo*)next())) {
3817 Int_t uid = info->GetNumber();
3818 if (fClassIndex->fArray[uid]) {
3819 list.Add(info);
3820 if (gDebug > 0) printf(" -class: %s info number %d saved\n",info->GetName(),uid);
3821
3822 // Add the IO customization rules to the list to be saved for the underlying
3823 // class but make sure to add them only once.
3824 TClass *clinfo = info->GetClass();
3825 if (clinfo && clinfo->GetSchemaRules()) {
3826 if ( classSet.find( clinfo ) == classSet.end() ) {
3827 if (gDebug > 0) printf(" -class: %s stored the I/O customization rules\n",info->GetName());
3828
3829 TObjArrayIter it( clinfo->GetSchemaRules()->GetRules() );
3830 ROOT::TSchemaRule *rule;
3831 while( (rule = (ROOT::TSchemaRule*)it.Next()) ) {
3832 TObjString *obj = new TObjString();
3833 rule->AsString(obj->String());
3834 listOfRules.Add(obj);
3835 }
3836 classSet.insert(clinfo);
3837 }
3838 }
3839 }
3840 }
3841
3842 // Write the StreamerInfo list even if it is empty.
3843 fClassIndex->fArray[0] = 2; //to prevent adding classes in TStreamerInfo::TagFile
3844
3845 if (listOfRules.GetEntries()) {
3846 // Only add the list of rules if we have something to say.
3847 list.Add(&listOfRules);
3848 }
3849
3850 //free previous StreamerInfo record
3852 //Create new key
3853 TKey key(&list,"StreamerInfo",GetBestBuffer(), this);
3854 fKeys->Remove(&key);
3855 fSeekInfo = key.GetSeekKey();
3856 fNbytesInfo = key.GetNbytes();
3857 SumBuffer(key.GetObjlen());
3858 key.WriteFile(0);
3859
3860 fClassIndex->fArray[0] = 0;
3861
3862 list.RemoveLast(); // remove the listOfRules.
3863}
3864
3865////////////////////////////////////////////////////////////////////////////////
3866/// Open a file for reading through the file cache.
3867///
3868/// The file will be downloaded to the cache and opened from there.
3869/// If the download fails, it will be opened remotely.
3870/// The file will be downloaded to the directory specified by SetCacheFileDir().
3872TFile *TFile::OpenFromCache(const char *name, Option_t *, const char *ftitle,
3873 Int_t compress, Int_t netopt)
3874{
3875 TFile *f = nullptr;
3876
3877 if (fgCacheFileDir == "") {
3878 ::Warning("TFile::OpenFromCache",
3879 "you want to read through a cache, but you have no valid cache "
3880 "directory set - reading remotely");
3881 ::Info("TFile::OpenFromCache", "set cache directory using TFile::SetCacheFileDir()");
3882 } else {
3883 TUrl fileurl(name);
3884
3885 if ((!strcmp(fileurl.GetProtocol(), "file"))) {
3886 // it makes no sense to read local files through a file cache
3887 if (!fgCacheFileForce)
3888 ::Warning("TFile::OpenFromCache",
3889 "you want to read through a cache, but you are reading "
3890 "local files - CACHEREAD disabled");
3891 } else {
3892 // this is a remote file and worthwhile to be put into the local cache
3893 // now create cachepath to put it
3894 TString cachefilepath;
3895 TString cachefilepathbasedir;
3896 cachefilepath = fgCacheFileDir;
3897 cachefilepath += fileurl.GetFile();
3898 cachefilepathbasedir = gSystem->GetDirName(cachefilepath);
3899 if ((gSystem->mkdir(cachefilepathbasedir, kTRUE) < 0) &&
3900 (gSystem->AccessPathName(cachefilepathbasedir, kFileExists))) {
3901 ::Warning("TFile::OpenFromCache","you want to read through a cache, but I "
3902 "cannot create the directory %s - CACHEREAD disabled",
3903 cachefilepathbasedir.Data());
3904 } else {
3905 // check if this should be a zip file
3906 if (strlen(fileurl.GetAnchor())) {
3907 // remove the anchor and change the target name
3908 cachefilepath += "__";
3909 cachefilepath += fileurl.GetAnchor();
3910 fileurl.SetAnchor("");
3911 }
3912 if (strstr(name,"zip=")) {
3913 // filter out this option and change the target cache name
3914 TString urloptions = fileurl.GetOptions();
3915 TString newoptions;
3916 TObjArray *objOptions = urloptions.Tokenize("&");
3917 Int_t optioncount = 0;
3918 TString zipname;
3919 for (Int_t n = 0; n < objOptions->GetEntries(); n++) {
3920 TString loption = ((TObjString*)objOptions->At(n))->GetName();
3921 TObjArray *objTags = loption.Tokenize("=");
3922 if (objTags->GetEntries() == 2) {
3923 TString key = ((TObjString*)objTags->At(0))->GetName();
3924 TString value = ((TObjString*)objTags->At(1))->GetName();
3925 if (key.CompareTo("zip", TString::kIgnoreCase)) {
3926 if (optioncount!=0) {
3927 newoptions += "&";
3928 }
3929 newoptions += key;
3930 newoptions += "=";
3931 newoptions += value;
3932 ++optioncount;
3933 } else {
3934 zipname = value;
3935 }
3936 }
3937 delete objTags;
3938 }
3939 delete objOptions;
3940 fileurl.SetOptions(newoptions.Data());
3941 cachefilepath += "__";
3942 cachefilepath += zipname;
3943 fileurl.SetAnchor("");
3944 }
3945
3946 Bool_t need2copy = kFALSE;
3947
3948 // check if file is in the cache
3949 Long_t id;
3950 Long64_t size;
3951 Long_t flags;
3952 Long_t modtime;
3953 if (!gSystem->GetPathInfo(cachefilepath, &id, &size, &flags, &modtime)) {
3954 // file is in the cache
3956 char cacheblock[256];
3957 char remotblock[256];
3958 // check the remote file for it's size and compare some magic bytes
3959 TString cfurl;
3960 cfurl = cachefilepath;
3961 cfurl += "?filetype=raw";
3962 TUrl rurl(name);
3963 TString ropt = rurl.GetOptions();
3964 ropt += "&filetype=raw";
3965 rurl.SetOptions(ropt);
3966
3967 Bool_t forcedcache = fgCacheFileForce;
3969
3970 TFile *cachefile = TFile::Open(cfurl, "READ");
3971 TFile *remotfile = TFile::Open(rurl.GetUrl(), "READ");
3972
3973 fgCacheFileForce = forcedcache;
3974
3975 if (!cachefile) {
3976 need2copy = kTRUE;
3977 ::Error("TFile::OpenFromCache",
3978 "cannot open the cache file to check cache consistency");
3979 return nullptr;
3980 }
3981
3982 if (!remotfile) {
3983 ::Error("TFile::OpenFromCache",
3984 "cannot open the remote file to check cache consistency");
3985 return nullptr;
3986 }
3987
3988 cachefile->Seek(0);
3989 remotfile->Seek(0);
3990
3991 if ((!cachefile->ReadBuffer(cacheblock,256)) &&
3992 (!remotfile->ReadBuffer(remotblock,256))) {
3993 if (memcmp(cacheblock, remotblock, 256)) {
3994 ::Warning("TFile::OpenFromCache", "the header of the cache file "
3995 "differs from the remote file - forcing an update");
3996 need2copy = kTRUE;
3997 }
3998 } else {
3999 ::Warning("TFile::OpenFromCache", "the header of the cache and/or "
4000 "remote file are not readable - forcing an update");
4001 need2copy = kTRUE;
4002 }
4003
4004 delete remotfile;
4005 delete cachefile;
4006 }
4007 } else {
4008 need2copy = kTRUE;
4009 }
4010
4011 // try to fetch the file (disable now the forced caching)
4012 Bool_t forcedcache = fgCacheFileForce;
4014 if (need2copy) {
4015 const auto cachefilepathtmp = cachefilepath + std::to_string(gSystem->GetPid()) + ".tmp";
4016 if (!TFile::Cp(name, cachefilepathtmp)) {
4017 ::Warning("TFile::OpenFromCache",
4018 "you want to read through a cache, but I "
4019 "cannot make a cache copy of %s - CACHEREAD disabled",
4020 cachefilepathbasedir.Data());
4021 fgCacheFileForce = forcedcache;
4022 return nullptr;
4023 }
4024 if (gSystem->AccessPathName(cachefilepath)) // then file _does not_ exist (weird convention)
4025 gSystem->Rename(cachefilepathtmp, cachefilepath);
4026 else // another process or thread already wrote a file with the same name while we were copying it
4027 gSystem->Unlink(cachefilepathtmp);
4028 }
4029 fgCacheFileForce = forcedcache;
4030 ::Info("TFile::OpenFromCache", "using local cache copy of %s [%s]", name, cachefilepath.Data());
4031 // finally we have the file and can open it locally
4032 fileurl.SetProtocol("file");
4033 fileurl.SetFile(cachefilepath);
4034
4035 TString tagfile;
4036 tagfile = cachefilepath;
4037 tagfile += ".ROOT.cachefile";
4038 // we symlink this file as a ROOT cached file
4039 gSystem->Symlink(gSystem->BaseName(cachefilepath), tagfile);
4040 return TFile::Open(fileurl.GetUrl(), "READ", ftitle, compress, netopt);
4041 }
4042 }
4043 }
4044
4045 // Failed
4046 return f;
4047}
4048
4049////////////////////////////////////////////////////////////////////////////////
4050/// Create / open a file
4051///
4052/// The type of the file can be either a
4053/// TFile, TNetFile, TWebFile or any TFile derived class for which an
4054/// plugin library handler has been registered with the plugin manager
4055/// (for the plugin manager see the TPluginManager class). The returned
4056/// type of TFile depends on the file name specified by 'url'.
4057/// If 'url' is a '|'-separated list of file URLs, the 'URLs' are tried
4058/// sequentially in the specified order until a successful open.
4059/// If the file starts with "root:", "roots:" or "rootk:" a TNetFile object
4060/// will be returned, with "http:" a TWebFile, with "file:" a local TFile,
4061/// etc. (see the list of TFile plugin handlers in $ROOTSYS/etc/system.rootrc
4062/// for regular expressions that will be checked) and as last a local file will
4063/// be tried.
4064/// Before opening a file via TNetFile a check is made to see if the URL
4065/// specifies a local file. If that is the case the file will be opened
4066/// via a normal TFile. To force the opening of a local file via a
4067/// TNetFile use either TNetFile directly or specify as host "localhost".
4068/// The netopt argument is only used by TNetFile. For the meaning of the
4069/// options and other arguments see the constructors of the individual
4070/// file classes. In case of error, it returns a nullptr.
4071///
4072/// For TFile implementations supporting asynchronous file open, see
4073/// TFile::AsyncOpen(...), it is possible to request a timeout with the
4074/// option <b>`TIMEOUT=<secs>`</b>: the timeout must be specified in seconds and
4075/// it will be internally checked with granularity of one millisec.
4076/// For remote files there is the option: <b>CACHEREAD</b> opens an existing
4077/// file for reading through the file cache. The file will be downloaded to
4078/// the cache and opened from there. If the download fails, it will be opened remotely.
4079/// The file will be downloaded to the directory specified by SetCacheFileDir().
4080///
4081/// *The caller is responsible for deleting the pointer.*
4082/// In READ mode, a nullptr is returned if the file does not exist or cannot be opened.
4083/// In CREATE mode, a nullptr is returned if the file already exists or cannot be created.
4084/// In RECREATE mode, a nullptr is returned if the file can not be created.
4085/// In UPDATE mode, a nullptr is returned if the file cannot be created or opened.
4087TFile *TFile::Open(const char *url, Option_t *options, const char *ftitle,
4088 Int_t compress, Int_t netopt)
4089{
4091 TFile *f = nullptr;
4093
4094 // Check input
4095 if (!url || strlen(url) <= 0) {
4096 ::Error("TFile::Open", "no url specified");
4097 return f;
4098 }
4099
4100 TString expandedUrl(url);
4101 gSystem->ExpandPathName(expandedUrl);
4102
4103#ifdef R__UNIX
4104 // If URL is a file on an EOS FUSE mount, attempt redirection to XRootD protocol.
4105 if (gEnv->GetValue("TFile.CrossProtocolRedirects", 1) == 1) {
4106 TUrl fileurl(expandedUrl, /* default is file */ kTRUE);
4107 if (strcmp(fileurl.GetProtocol(), "file") == 0) {
4108 ssize_t len = getxattr(fileurl.GetFile(), "eos.url.xroot", nullptr, 0);
4109 if (len > 0) {
4110 std::string xurl(len, 0);
4111 if (getxattr(fileurl.GetFile(), "eos.url.xroot", &xurl[0], len) == len) {
4112 if ((f = TFile::Open(xurl.c_str(), options, ftitle, compress, netopt))) {
4113 if (!f->IsZombie()) {
4114 return f;
4115 } else {
4116 delete f;
4117 f = nullptr;
4118 }
4119 }
4120 }
4121 }
4122 }
4123 }
4124#endif
4125
4126 // If a timeout has been specified extract the value and try to apply it (it requires
4127 // support for asynchronous open, though; the following is completely transparent if
4128 // such support if not available for the required protocol)
4129 TString opts(options);
4130 Int_t ito = opts.Index("TIMEOUT=");
4131 if (ito != kNPOS) {
4132 TString sto = opts(ito + std::char_traits<char>::length("TIMEOUT="), opts.Length());
4133 while (!(sto.IsDigit()) && !(sto.IsNull())) { sto.Remove(sto.Length()-1,1); }
4134 if (!(sto.IsNull())) {
4135 // Timeout in millisecs
4136 Int_t toms = sto.Atoi() * 1000;
4137 if (gDebug > 0) ::Info("TFile::Open", "timeout of %d millisec requested", toms);
4138 // Remove from the options field
4139 sto.Insert(0, "TIMEOUT=");
4140 opts.ReplaceAll(sto, "");
4141 // Asynchronous open
4142 TFileOpenHandle *fh = TFile::AsyncOpen(expandedUrl, opts, ftitle, compress, netopt);
4143 // Check the result in steps of 1 millisec
4145 aos = TFile::GetAsyncOpenStatus(fh);
4146 Int_t xtms = toms;
4147 while (aos == TFile::kAOSInProgress && xtms > 0) {
4148 gSystem->Sleep(1);
4149 xtms -= 1;
4150 aos = TFile::GetAsyncOpenStatus(fh);
4151 }
4152 if (aos == TFile::kAOSNotAsync || aos == TFile::kAOSSuccess) {
4153 // Do open the file now
4154 f = TFile::Open(fh);
4155 if (gDebug > 0) {
4156 if (aos == TFile::kAOSSuccess)
4157 ::Info("TFile::Open", "waited %d millisec for asynchronous open", toms - xtms);
4158 else
4159 ::Info("TFile::Open", "timeout option not supported (requires asynchronous"
4160 " open support)");
4161 }
4162 } else {
4163 if (xtms <= 0)
4164 ::Error("TFile::Open", "timeout expired while opening '%s'", expandedUrl.Data());
4165 // Cleanup the request
4166 SafeDelete(fh);
4167 }
4168 // Done
4169 return f;
4170 } else {
4171 ::Warning("TFile::Open", "incomplete 'TIMEOUT=' option specification - ignored");
4172 opts.ReplaceAll("TIMEOUT=", "");
4173 }
4174 }
4175
4176 // We will use this from now on
4177 const char *option = opts;
4178
4179 // Many URLs? Redirect output and print errors in case of global failure
4180 TString namelist(expandedUrl);
4181 Ssiz_t ip = namelist.Index("|");
4182 Bool_t rediroutput = (ip != kNPOS &&
4183 ip != namelist.Length()-1 && gDebug <= 0) ? kTRUE : kFALSE;
4185 if (rediroutput) {
4186 TString outf = ".TFileOpen_";
4187 FILE *fout = gSystem->TempFileName(outf);
4188 if (fout) {
4189 fclose(fout);
4190 gSystem->RedirectOutput(outf, "w", &rh);
4191 }
4192 }
4193
4194 // Try sequentially all names in 'names'
4195 TString name, n;
4196 Ssiz_t from = 0;
4197 while (namelist.Tokenize(n, from, "|") && !f) {
4198
4199 // check if we read through a file cache
4200 if (!strcasecmp(option, "CACHEREAD") ||
4201 ((!strcasecmp(option,"READ") || !option[0]) && fgCacheFileForce)) {
4202 // Try opening the file from the cache
4203 if ((f = TFile::OpenFromCache(n, option, ftitle, compress, netopt)))
4204 return f;
4205 }
4206
4208
4209 // change names to be recognized by the plugin manager
4210 // e.g. /protocol/path/to/file.root -> protocol:/path/to/file.root
4211 TUrl urlname(n, kTRUE);
4212 name = urlname.GetUrl();
4213 // Check first if a pending async open request matches this one
4216 TFileOpenHandle *fh = nullptr;
4217 while ((fh = (TFileOpenHandle *)nxr()))
4218 if (fh->Matches(name))
4219 return TFile::Open(fh);
4220 }
4221
4222 TString urlOptions(urlname.GetOptions());
4223 if (urlOptions.BeginsWith("pmerge") || urlOptions.Contains("&pmerge") || urlOptions.Contains(" pmerge")) {
4224 type = kMerge;
4225
4226 // Pass the full name including the url options:
4227 f = (TFile*) gROOT->ProcessLineFast(TString::Format("new TParallelMergingFile(\"%s\",\"%s\",\"%s\",%d)",n.Data(),option,ftitle,compress));
4228
4229 } else {
4230 // Resolve the file type; this also adjusts names
4231 TString lfname = gEnv->GetValue("Path.Localroot", "");
4232 type = GetType(name, option, &lfname);
4233
4234 if (type == kLocal) {
4235
4236 // Local files
4237 if (lfname.IsNull()) {
4238 urlname.SetHost("");
4239 urlname.SetProtocol("file");
4240 lfname = urlname.GetUrl();
4241 }
4242 f = new TFile(lfname.Data(), option, ftitle, compress);
4243
4244 } else if (type == kNet) {
4245
4246 // Network files
4247 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name))) {
4248 if (h->LoadPlugin() == -1)
4249 return nullptr;
4250 f = (TFile*) h->ExecPlugin(5, name.Data(), option, ftitle, compress, netopt);
4251 }
4252
4253 } else if (type == kWeb) {
4254
4255 // Web files
4256 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name))) {
4257 if (h->LoadPlugin() == -1)
4258 return nullptr;
4259 f = (TFile*) h->ExecPlugin(2, name.Data(), option);
4260 }
4261
4262 } else if (type == kFile) {
4263
4264 // 'file:' protocol
4265 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) &&
4266 h->LoadPlugin() == 0) {
4267 name.ReplaceAll("file:", "");
4268 f = (TFile*) h->ExecPlugin(4, name.Data(), option, ftitle, compress);
4269 } else
4270 f = new TFile(name.Data(), option, ftitle, compress);
4271
4272 } else {
4273
4274 // no recognized specification: try the plugin manager
4275 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name.Data()))) {
4276 if (h->LoadPlugin() == -1)
4277 return nullptr;
4278 TClass *cl = TClass::GetClass(h->GetClass());
4279 if (cl && cl->InheritsFrom("TNetFile"))
4280 f = (TFile*) h->ExecPlugin(5, name.Data(), option, ftitle, compress, netopt);
4281 else
4282 f = (TFile*) h->ExecPlugin(4, name.Data(), option, ftitle, compress);
4283 } else {
4284 // Just try to open it locally but via TFile::Open, so that we pick-up the correct
4285 // plug-in in the case file name contains information about a special backend (e.g.)
4286 if (strcmp(name, urlname.GetFileAndOptions()) != 0)
4287 f = TFile::Open(urlname.GetFileAndOptions(), option, ftitle, compress);
4288 }
4289 }
4290 }
4291
4292 if (f && f->IsZombie()) {
4293 TString newUrl = f->GetNewUrl();
4294 delete f;
4295 if( newUrl.Length() && (newUrl != name) && gEnv->GetValue("TFile.CrossProtocolRedirects", 1) )
4296 f = TFile::Open( newUrl, option, ftitle, compress );
4297 else
4298 f = nullptr;
4299 }
4300 }
4301
4302 if (rediroutput) {
4303 // Restore output to stdout
4304 gSystem->RedirectOutput(0, "", &rh);
4305 // If we failed print error messages
4306 if (!f)
4307 gSystem->ShowOutput(&rh);
4308 // Remove the file
4309 gSystem->Unlink(rh.fFile);
4310 }
4311
4312 // if the file is writable, non local, and not opened in raw mode
4313 // we create a default write cache of 512 KBytes
4314 if (type != kLocal && type != kFile &&
4315 f && f->IsWritable() && !f->IsRaw()) {
4316 new TFileCacheWrite(f, 1);
4317 }
4318
4319 return f;
4320}
4321
4322////////////////////////////////////////////////////////////////////////////////
4323/// Submit an asynchronous open request.
4324
4325/// See TFile::Open(const char *, ...) for an
4326/// explanation of the arguments. A handler is returned which is to be passed
4327/// to TFile::Open(TFileOpenHandle *) to get the real TFile instance once
4328/// the file is open.
4329/// This call never blocks and it is provided to allow parallel submission
4330/// of file opening operations expected to take a long time.
4331/// TFile::Open(TFileOpenHandle *) may block if the file is not yet ready.
4332/// The sequence
4333///
4334/// TFile::Open(TFile::AsyncOpen(const char *, ...))
4335///
4336/// is equivalent to
4337///
4338/// TFile::Open(const char *, ...)
4339///
4340/// To be effective, the underlying TFile implementation must be able to
4341/// support asynchronous open functionality. Currently, only TNetXNGFile
4342/// supports it. If the functionality is not implemented, this call acts
4343/// transparently by returning an handle with the arguments for the
4344/// standard synchronous open run by TFile::Open(TFileOpenHandle *).
4345/// The retuned handle will be adopted by TFile after opening completion
4346/// in TFile::Open(TFileOpenHandle *); if opening is not finalized the
4347/// handle must be deleted by the caller.
4350 const char *ftitle, Int_t compress,
4351 Int_t netopt)
4352{
4353 TFileOpenHandle *fh = nullptr;
4354 TFile *f = nullptr;
4355 Bool_t notfound = kTRUE;
4356
4357 // Check input
4358 if (!url || strlen(url) <= 0) {
4359 ::Error("TFile::AsyncOpen", "no url specified");
4360 return fh;
4361 }
4362
4363 // Many URLs? Redirect output and print errors in case of global failure
4364 TString namelist(url);
4365 gSystem->ExpandPathName(namelist);
4366 Ssiz_t ip = namelist.Index("|");
4367 Bool_t rediroutput = (ip != kNPOS &&
4368 ip != namelist.Length()-1 && gDebug <= 0) ? kTRUE : kFALSE;
4370 if (rediroutput) {
4371 TString outf = ".TFileAsyncOpen_";
4372 FILE *fout = gSystem->TempFileName(outf);
4373 if (fout) {
4374 fclose(fout);
4375 gSystem->RedirectOutput(outf, "w", &rh);
4376 }
4377 }
4378
4379 // Try sequentially all names in 'names'
4380 TString name, n;
4381 Ssiz_t from = 0;
4382 while (namelist.Tokenize(n, from, "|") && !f) {
4383
4384 // change names to be recognized by the plugin manager
4385 // e.g. /protocol/path/to/file.root -> protocol:/path/to/file.root
4386 TUrl urlname(n, kTRUE);
4387 name = urlname.GetUrl();
4388
4389 // Resolve the file type; this also adjusts names
4391
4392 TPluginHandler *h = nullptr;
4393
4394 // Here we send the asynchronous request if the functionality is implemented
4395 if (type == kNet) {
4396 // Network files
4397 if ((h = gROOT->GetPluginManager()->FindHandler("TFile", name)) &&
4398 !strcmp(h->GetClass(),"TNetXNGFile")
4399 && h->LoadPlugin() == 0) {
4400 f = (TFile*) h->ExecPlugin(6, name.Data(), option, ftitle, compress, netopt, kTRUE);
4401 notfound = kFALSE;
4402 }
4403 }
4404 }
4405
4406 if (rediroutput) {
4407 // Restore output to stdout
4408 gSystem->RedirectOutput(0, "", &rh);
4409 // If we failed print error messages
4410 if (!notfound && !f)
4411 gSystem->ShowOutput(&rh);
4412 // Remove the file
4413 gSystem->Unlink(rh.fFile);
4414 }
4415
4416 // Make sure that no error occurred
4417 if (notfound) {
4418 SafeDelete(f);
4419 // Save the arguments in the handler, so that a standard open can be
4420 // attempted later on
4421 fh = new TFileOpenHandle(name, option, ftitle, compress, netopt);
4422 } else if (f) {
4423 // Fill the opaque handler to be use to attach the file later on
4424 fh = new TFileOpenHandle(f);
4425 }
4426
4427 // Record this request
4428 if (fh) {
4429 // Create the lst, if not done already
4433 }
4434
4435 // We are done
4436 return fh;
4437}
4438
4439////////////////////////////////////////////////////////////////////////////////
4440/// Waits for the completion of an asynchronous open request.
4441///
4442/// Returns the pointer to the associated TFile, transferring ownership of the
4443/// handle to the TFile instance.
4446{
4447 TFile *f = nullptr;
4448
4449 // Note that the request may have failed
4450 if (fh && fgAsyncOpenRequests) {
4451 // Remove it from the pending list: we need to do it at this level to avoid
4452 // recursive calls in the standard TFile::Open
4454 // Was asynchronous open functionality implemented?
4455 if ((f = fh->GetFile()) && !(f->IsZombie())) {
4456 // Yes: wait for the completion of the open phase, if needed
4457 Bool_t cr = (!strcmp(f->GetOption(),"CREATE") ||
4458 !strcmp(f->GetOption(),"RECREATE") ||
4459 !strcmp(f->GetOption(),"NEW")) ? kTRUE : kFALSE;
4460 f->Init(cr);
4461 } else {
4462 // No: process a standard open
4463 f = TFile::Open(fh->GetName(), fh->GetOpt(), fh->GetTitle(),
4464 fh->GetCompress(), fh->GetNetOpt());
4465 }
4466
4467 // Adopt the handle instance in the TFile instance so that it gets
4468 // automatically cleaned up
4469 if (f) f->fAsyncHandle = fh;
4470 }
4471
4472 // We are done
4473 return f;
4474}
4475
4476////////////////////////////////////////////////////////////////////////////////
4477/// Interface to system open. All arguments like in POSIX open().
4479Int_t TFile::SysOpen(const char *pathname, Int_t flags, UInt_t mode)
4480{
4481#if defined(R__WINGCC)
4482 // ALWAYS use binary mode - even cygwin text should be in unix format
4483 // although this is posix default it has to be set explicitly
4484 return ::open(pathname, flags | O_BINARY, mode);
4485#elif defined(R__SEEK64)
4486 return ::open64(pathname, flags, mode);
4487#else
4488 return ::open(pathname, flags, mode);
4489#endif
4490}
4491
4492////////////////////////////////////////////////////////////////////////////////
4493/// Interface to system close. All arguments like in POSIX close().
4496{
4497 if (fd < 0) return 0;
4498 return ::close(fd);
4499}
4500
4501////////////////////////////////////////////////////////////////////////////////
4502/// Interface to system read. All arguments like in POSIX read().
4504Int_t TFile::SysRead(Int_t fd, void *buf, Int_t len)
4505{
4506 return ::read(fd, buf, len);
4507}
4508
4509////////////////////////////////////////////////////////////////////////////////
4510/// Interface to system write. All arguments like in POSIX write().
4512Int_t TFile::SysWrite(Int_t fd, const void *buf, Int_t len)
4513{
4514 return ::write(fd, buf, len);
4515}
4516////////////////////////////////////////////////////////////////////////////////
4517/// Interface to system lseek.
4518///
4519/// All arguments like in POSIX lseek()
4520/// except that the offset and return value are of a type which are
4521/// able to handle 64 bit file systems.
4524{
4525#if defined (R__SEEK64)
4526 return ::lseek64(fd, offset, whence);
4527#elif defined(WIN32)
4528 return ::_lseeki64(fd, offset, whence);
4529#else
4530 return ::lseek(fd, offset, whence);
4531#endif
4532}
4533
4534////////////////////////////////////////////////////////////////////////////////
4535/// Return file stat information.
4536///
4537/// The interface and return value is
4538/// identical to TSystem::GetPathInfo(). The function returns 0 in
4539/// case of success and 1 if the file could not be stat'ed.
4542 Long_t *modtime)
4543{
4544 return gSystem->GetPathInfo(fRealName, id, size, flags, modtime);
4545}
4546
4547////////////////////////////////////////////////////////////////////////////////
4548/// Interface to system fsync. All arguments like in POSIX fsync().
4551{
4552 if (TestBit(kDevNull)) return 0;
4553
4554#ifndef WIN32
4555 return ::fsync(fd);
4556#else
4557 return ::_commit(fd);
4558#endif
4559}
4560
4561////////////////////////////////////////////////////////////////////////////////
4562/// Return the total number of bytes written so far to the file.
4565{
4567}
4568
4569////////////////////////////////////////////////////////////////////////////////
4570/// Static function returning the total number of bytes read from all files.
4573{
4574 return fgBytesRead;
4575}
4576
4577////////////////////////////////////////////////////////////////////////////////
4578/// Static function returning the total number of bytes written to all files.
4579/// Does not take into account what might still be in the write caches.
4582{
4583 return fgBytesWrite;
4584}
4585
4586////////////////////////////////////////////////////////////////////////////////
4587/// Static function returning the total number of read calls from all files.
4590{
4591 return fgReadCalls;
4592}
4593
4594////////////////////////////////////////////////////////////////////////////////
4595/// Static function returning the readahead buffer size.
4598{
4599 return fgReadaheadSize;
4600}
4601
4602//______________________________________________________________________________
4604
4605//______________________________________________________________________________
4607
4608//______________________________________________________________________________
4610
4611//______________________________________________________________________________
4612void TFile::SetFileReadCalls(Int_t readcalls) { fgReadCalls = readcalls; }
4613
4614//______________________________________________________________________________
4616
4617//______________________________________________________________________________
4619
4620////////////////////////////////////////////////////////////////////////////////
4621/// Sets the directory where to locally stage/cache remote files.
4622/// If the directory is not writable by us return kFALSE.
4624Bool_t TFile::SetCacheFileDir(std::string_view cachedir, Bool_t operatedisconnected,
4625 Bool_t forcecacheread )
4626{
4627 TString cached{cachedir};
4628 if (!cached.EndsWith("/"))
4629 cached += "/";
4630
4631 if (gSystem->AccessPathName(cached, kFileExists)) {
4632 // try to create it
4633 gSystem->mkdir(cached, kTRUE);
4634 if (gSystem->AccessPathName(cached, kFileExists)) {
4635 ::Error("TFile::SetCacheFileDir", "no sufficient permissions on cache directory %s or cannot create it", TString(cachedir).Data());
4636 fgCacheFileDir = "";
4637 return kFALSE;
4638 }
4639 gSystem->Chmod(cached, 0700);
4640 }
4642 gSystem->Chmod(cached, 0700);
4643 fgCacheFileDir = cached;
4644 fgCacheFileDisconnected = operatedisconnected;
4645 fgCacheFileForce = forcecacheread;
4646 return kTRUE;
4647}
4648
4649////////////////////////////////////////////////////////////////////////////////
4650/// Get the directory where to locally stage/cache remote files.
4652const char *TFile::GetCacheFileDir()
4653{
4654 return fgCacheFileDir;
4655}
4656
4657////////////////////////////////////////////////////////////////////////////////
4658/// Try to shrink the cache to the desired size.
4659///
4660/// With the clenupinterval you can specify the minimum amount of time after
4661/// the previous cleanup before the cleanup operation is repeated in
4662/// the cache directory
4664Bool_t TFile::ShrinkCacheFileDir(Long64_t shrinksize, Long_t cleanupinterval)
4665{
4666 if (fgCacheFileDir == "") {
4667 return kFALSE;
4668 }
4669
4670 // check the last clean-up in the cache
4671 Long_t id;
4672 Long64_t size;
4673 Long_t flags;
4674 Long_t modtime;
4675
4676 TString cachetagfile = fgCacheFileDir;
4677 cachetagfile += ".tag.ROOT.cache";
4678 if (!gSystem->GetPathInfo(cachetagfile, &id, &size, &flags, &modtime)) {
4679 // check the time passed since last cache cleanup
4680 Long_t lastcleanuptime = ((Long_t)time(0) - modtime);
4681 if (lastcleanuptime < cleanupinterval) {
4682 ::Info("TFile::ShrinkCacheFileDir", "clean-up is skipped - last cleanup %lu seconds ago - you requested %lu", lastcleanuptime, cleanupinterval);
4683 return kTRUE;
4684 }
4685 }
4686
4687 // (re-)create the cache tag file
4688 cachetagfile += "?filetype=raw";
4689 TFile *tagfile = nullptr;
4690
4691 if (!(tagfile = TFile::Open(cachetagfile, "RECREATE"))) {
4692 ::Error("TFile::ShrinkCacheFileDir", "cannot create the cache tag file %s", cachetagfile.Data());
4693 return kFALSE;
4694 }
4695
4696 // the shortest garbage collector in the world - one long line of PERL - unlinks files only,
4697 // if there is a symbolic link with '.ROOT.cachefile' for safety ;-)
4698
4699 TString cmd;
4700#if defined(R__WIN32)
4701 cmd = "echo <TFile::ShrinkCacheFileDir>: cleanup to be implemented";
4702#elif defined(R__MACOSX)
4703 cmd.Form("perl -e 'my $cachepath = \"%s\"; my $cachesize = %lld;my $findcommand=\"find $cachepath -type f -exec stat -f \\\"\\%%a::\\%%N::\\%%z\\\" \\{\\} \\\\\\;\";my $totalsize=0;open FIND, \"$findcommand | sort -k 1 |\";while (<FIND>) { my ($accesstime, $filename, $filesize) = split \"::\",$_; $totalsize += $filesize;if ($totalsize > $cachesize) {if ( ( -e \"${filename}.ROOT.cachefile\" ) || ( -e \"${filename}\" ) ) {unlink \"$filename.ROOT.cachefile\";unlink \"$filename\";}}}close FIND;' ", fgCacheFileDir.Data(),shrinksize);
4704#else
4705 cmd.Form("perl -e 'my $cachepath = \"%s\"; my $cachesize = %lld;my $findcommand=\"find $cachepath -type f -exec stat -c \\\"\\%%x::\\%%n::\\%%s\\\" \\{\\} \\\\\\;\";my $totalsize=0;open FIND, \"$findcommand | sort -k 1 |\";while (<FIND>) { my ($accesstime, $filename, $filesize) = split \"::\",$_; $totalsize += $filesize;if ($totalsize > $cachesize) {if ( ( -e \"${filename}.ROOT.cachefile\" ) || ( -e \"${filename}\" ) ) {unlink \"$filename.ROOT.cachefile\";unlink \"$filename\";}}}close FIND;' ", fgCacheFileDir.Data(),shrinksize);
4706#endif
4707
4708 tagfile->WriteBuffer(cmd, 4096);
4709 delete tagfile;
4710
4711 if ((gSystem->Exec(cmd)) != 0) {
4712 ::Error("TFile::ShrinkCacheFileDir", "error executing clean-up script");
4713 return kFALSE;
4714 }
4715
4716 return kTRUE;
4717}
4718
4719////////////////////////////////////////////////////////////////////////////////
4720/// Sets open timeout time (in ms). Returns previous timeout value.
4723{
4724 UInt_t to = fgOpenTimeout;
4725 fgOpenTimeout = timeout;
4726 return to;
4727}
4728
4729////////////////////////////////////////////////////////////////////////////////
4730/// Returns open timeout (in ms).
4733{
4734 return fgOpenTimeout;
4735}
4736
4737////////////////////////////////////////////////////////////////////////////////
4738/// Sets only staged flag. Returns previous value of flag.
4739/// When true we check before opening the file if it is staged, if not,
4740/// the open fails.
4743{
4745 fgOnlyStaged = onlystaged;
4746 return f;
4747}
4748
4749////////////////////////////////////////////////////////////////////////////////
4750/// Returns staged only flag.
4753{
4754 return fgOnlyStaged;
4755}
4756
4757////////////////////////////////////////////////////////////////////////////////
4758/// Return kTRUE if 'url' matches the coordinates of this file.
4759///
4760/// The check is implementation dependent and may need to be overload
4761/// by each TFile implementation relying on this check.
4762/// The default implementation checks the file name only.
4764Bool_t TFile::Matches(const char *url)
4765{
4766 // Check the full URL, including port and FQDN.
4767 TUrl u(url);
4768
4769 // Check
4770 if (!strcmp(u.GetFile(), fUrl.GetFile())) {
4771 // Check ports
4772 if (u.GetPort() == fUrl.GetPort()) {
4773 if (!strcmp(u.GetHostFQDN(), fUrl.GetHostFQDN())) {
4774 // Ok, coordinates match
4775 return kTRUE;
4776 }
4777 }
4778 }
4779
4780 // Default is not matching
4781 return kFALSE;
4782}
4783
4784////////////////////////////////////////////////////////////////////////////////
4785/// Return kTRUE if this async request matches the open request
4786/// specified by 'url'
4788Bool_t TFileOpenHandle::Matches(const char *url)
4789{
4790 if (fFile) {
4791 return fFile->Matches(url);
4792 } else if (fName.Length() > 0){
4793 // Deep check of URLs
4794 TUrl u(url);
4795 TUrl uref(fName);
4796 if (!strcmp(u.GetFile(), uref.GetFile())) {
4797 // Check ports
4798 if (u.GetPort() == uref.GetPort()) {
4799 // Check also the host name
4800 if (!strcmp(u.GetHostFQDN(), uref.GetHostFQDN())) {
4801 // Ok, coordinates match
4802 return kTRUE;
4803 }
4804 }
4805 }
4806 }
4807
4808 // Default is not matching
4809 return kFALSE;
4810}
4811
4812////////////////////////////////////////////////////////////////////////////////
4813/// Resolve the file type as a function of the protocol field in 'name'
4814///
4815/// If defined, the string 'prefix' is added when testing the locality of
4816/// a 'name' with network-like structure (i.e. root://host//path); if the file
4817/// is local, on return 'prefix' will contain the actual local path of the file.
4820{
4822
4823 TPMERegexp re("^(root|xroot).*", "i");
4824 if (re.Match(name)) {
4825 //
4826 // Should be a network file ...
4827 type = kNet;
4828 // ... but make sure that is not local or that a remote-like connection
4829 // is forced. Treat it as local if:
4830 // i) the url points to the localhost, the file will be opened in
4831 // readonly mode and the current user has read access;
4832 // ii) the specified user is equal to the current user then open local
4833 // TFile.
4834 Bool_t localFile = kFALSE;
4835 TUrl url(name);
4836 //
4837 // Check whether we should try to optimize for local files
4838 Bool_t forceRemote = gEnv->GetValue("Path.ForceRemote", 0);
4839 forceRemote = (forceRemote) ? kTRUE : gEnv->GetValue("TFile.ForceRemote", 0);
4840 TString opts = url.GetOptions();
4841 if (opts.Contains("remote=1"))
4842 forceRemote = kTRUE;
4843 else if (opts.Contains("remote=0"))
4844 forceRemote = kFALSE;
4845 if (!forceRemote) {
4846 // Generic locality test
4847 localFile = gSystem->IsPathLocal(name);
4848 if (localFile) {
4849 // Local path including the prefix
4850 const char *fname = url.GetFileAndOptions();
4851 TString lfname;
4852 if (fname[0] == '/') {
4853 if (prefix)
4854 lfname.Form("%s%s", prefix->Data(), fname);
4855 else
4856 lfname = fname;
4857 } else if (fname[0] == '~' || fname[0] == '$') {
4858 lfname = fname;
4859 } else {
4860 lfname.Form("%s/%s", gSystem->HomeDirectory(), fname);
4861 }
4862 // If option "READ" test existence and access
4863 TString opt = option;
4864 Bool_t read = (opt.IsNull() ||
4865 !opt.CompareTo("READ", TString::kIgnoreCase)) ? kTRUE : kFALSE;
4866 if (read) {
4867 TString fn = TUrl(lfname).GetFile();
4868 if (!gSystem->ExpandPathName(fn)) {
4870 localFile = kFALSE;
4871 }
4872 }
4873 // Return full local path if requested (and if the case)
4874 if (localFile && prefix)
4875 *prefix = lfname;
4876 }
4877 }
4878 //
4879 // Adjust the type according to findings
4880 type = (localFile) ? kLocal : type;
4881 } else if (TPMERegexp("^(http[s]?|s3http[s]?|[a]?s3|gs|gshttp[s]?){1}:", "i").Match(name)) {
4882 //
4883 // Web file
4884 type = kWeb;
4885 } else if (!strncmp(name, "file:", 5)) {
4886 //
4887 // 'file' protocol
4888 type = kFile;
4889 }
4890 // We are done
4891 return type;
4892}
4893
4894////////////////////////////////////////////////////////////////////////////////
4895/// Get status of the async open request related to 'name'.
4898{
4899 // Check the list of pending async open requests
4902 TFileOpenHandle *fh = nullptr;
4903 while ((fh = (TFileOpenHandle *)nxr()))
4904 if (fh->Matches(name))
4905 return TFile::GetAsyncOpenStatus(fh);
4906 }
4907
4908 // Check also the list of files open
4910 TSeqCollection *of = gROOT->GetListOfFiles();
4911 if (of && (of->GetSize() > 0)) {
4912 TIter nxf(of);
4913 TFile *f = nullptr;
4914 while ((f = (TFile *)nxf()))
4915 if (f->Matches(name))
4916 return f->GetAsyncOpenStatus();
4917 }
4918
4919 // Default is synchronous mode
4920 return kAOSNotAsync;
4921}
4922
4923////////////////////////////////////////////////////////////////////////////////
4924/// Get status of the async open request related to 'handle'.
4927{
4928 if (handle && handle->fFile) {
4929 if (!handle->fFile->IsZombie())
4930 return handle->fFile->GetAsyncOpenStatus();
4931 else
4932 return TFile::kAOSFailure;
4933 }
4934
4935 // Default is synchronous mode
4936 return TFile::kAOSNotAsync;
4937}
4938
4939////////////////////////////////////////////////////////////////////////////////
4940/// Get final URL for file being opened asynchronously.
4941/// Returns 0 is the information is not yet available.
4943const TUrl *TFile::GetEndpointUrl(const char* name)
4944{
4945 // Check the list of pending async open requests
4948 TFileOpenHandle *fh = nullptr;
4949 while ((fh = (TFileOpenHandle *)nxr()))
4950 if (fh->Matches(name))
4951 if (fh->fFile)
4952 return fh->fFile->GetEndpointUrl();
4953 }
4954
4955 // Check also the list of files open
4957 TSeqCollection *of = gROOT->GetListOfFiles();
4958 if (of && (of->GetSize() > 0)) {
4959 TIter nxf(of);
4960 TFile *f = nullptr;
4961 while ((f = (TFile *)nxf()))
4962 if (f->Matches(name))
4963 return f->GetEndpointUrl();
4964 }
4965
4966 // Information not yet available
4967 return (const TUrl *)nullptr;
4968}
4969
4970////////////////////////////////////////////////////////////////////////////////
4971/// Print file copy progress.
4973void TFile::CpProgress(Long64_t bytesread, Long64_t size, TStopwatch &watch)
4974{
4975 fprintf(stderr, "[TFile::Cp] Total %.02f MB\t|", (Double_t)size/1048576);
4976
4977 for (int l = 0; l < 20; l++) {
4978 if (size > 0) {
4979 if (l < 20*bytesread/size)
4980 fprintf(stderr, "=");
4981 else if (l == 20*bytesread/size)
4982 fprintf(stderr, ">");
4983 else if (l > 20*bytesread/size)
4984 fprintf(stderr, ".");
4985 } else
4986 fprintf(stderr, "=");
4987 }
4988 // Allow to update the GUI while uploading files
4990 watch.Stop();
4991 Double_t lCopy_time = watch.RealTime();
4992 fprintf(stderr, "| %.02f %% [%.01f MB/s]\r",
4993 100.0*(size?(bytesread/((float)size)):1), (lCopy_time>0.)?bytesread/lCopy_time/1048576.:0.);
4994 watch.Continue();
4995}
4996
4997////////////////////////////////////////////////////////////////////////////////
4998/// Allows to copy this file to the dst URL. Returns kTRUE in case of success,
4999/// kFALSE otherwise.
5001Bool_t TFile::Cp(const char *dst, Bool_t progressbar, UInt_t buffersize)
5002{
5003 Bool_t rmdestiferror = kFALSE;
5004 TStopwatch watch;
5005 Bool_t success = kFALSE;
5006
5007 TUrl dURL(dst, kTRUE);
5008
5009 TString oopt = "RECREATE";
5010 TString ourl = dURL.GetUrl();
5011
5012 // Files will be open in RAW mode
5013 TString raw = "filetype=raw";
5014
5015 // Set optimization options for the destination file
5016 TString opt = dURL.GetOptions();
5017 if (opt != "") opt += "&";
5018 opt += raw;
5019
5020 // AliEn files need to know where the source file is
5021 if (!strcmp(dURL.GetProtocol(), "alien"))
5022 opt += TString::Format("&source=%s", GetName());
5023
5024 dURL.SetOptions(opt);
5025
5026 char *copybuffer = nullptr;
5027
5028 TFile *sfile = this;
5029 TFile *dfile = nullptr;
5030
5031 // "RECREATE" does not work always well with XROOTD
5032 // namely when some pieces of the path are missing;
5033 // we force "NEW" in such a case
5034 if (TFile::GetType(ourl, "") == TFile::kNet) {
5035 if (gSystem->AccessPathName(ourl)) {
5036 oopt = "NEW";
5037 // Force creation of the missing parts of the path
5038 opt += "&mkpath=1";
5039 dURL.SetOptions(opt);
5040 }
5041 }
5042
5043 // Open destination file
5044 if (!(dfile = TFile::Open(dURL.GetUrl(), oopt))) {
5045 ::Error("TFile::Cp", "cannot open destination file %s", dst);
5046 goto copyout;
5047 }
5048
5049 // Probably we created a new file
5050 // We have to remove it in case of errors
5051 rmdestiferror = kTRUE;
5052
5053 sfile->Seek(0);
5054 dfile->Seek(0);
5055
5056 copybuffer = new char[buffersize];
5057 if (!copybuffer) {
5058 ::Error("TFile::Cp", "cannot allocate the copy buffer");
5059 goto copyout;
5060 }
5061
5062 Bool_t readop, writeop;
5063 Long64_t read, written, totalread, filesize, b00;
5064
5065 totalread = 0;
5066 filesize = sfile->GetSize();
5067
5068 watch.Start();
5069
5070 b00 = sfile->GetBytesRead();
5071
5072 do {
5073 if (progressbar) CpProgress(totalread, filesize,watch);
5074
5075 Long64_t b1 = sfile->GetBytesRead() - b00;
5076
5077 Long64_t readsize;
5078 if (filesize - b1 > (Long64_t)buffersize) {
5079 readsize = buffersize;
5080 } else {
5081 readsize = filesize - b1;
5082 }
5083
5084 if (readsize == 0) break;
5085
5086 Long64_t b0 = sfile->GetBytesRead();
5087 sfile->Seek(totalread,TFile::kBeg);
5088 readop = sfile->ReadBuffer(copybuffer, (Int_t)readsize);
5089 read = sfile->GetBytesRead() - b0;
5090 if ((read <= 0) || readop) {
5091 ::Error("TFile::Cp", "cannot read from source file %s. readsize=%lld read=%lld readop=%d",
5092 sfile->GetName(), readsize, read, readop);
5093 goto copyout;
5094 }
5095
5096 Long64_t w0 = dfile->GetBytesWritten();
5097 writeop = dfile->WriteBuffer(copybuffer, (Int_t)read);
5098 written = dfile->GetBytesWritten() - w0;
5099 if ((written != read) || writeop) {
5100 ::Error("TFile::Cp", "cannot write %lld bytes to destination file %s", read, dst);
5101 goto copyout;
5102 }
5103 totalread += read;
5104 } while (read == (Long64_t)buffersize);
5105
5106 if (progressbar) {
5107 CpProgress(totalread, filesize,watch);
5108 fprintf(stderr, "\n");
5109 }
5110
5111 success = kTRUE;
5112
5113copyout:
5114 if (dfile) dfile->Close();
5115
5116 if (dfile) delete dfile;
5117 if (copybuffer) delete[] copybuffer;
5118
5119 if (rmdestiferror && (success != kTRUE))
5120 gSystem->Unlink(dst);
5121
5122 watch.Stop();
5123 watch.Reset();
5124
5125 return success;
5126}
5127
5128////////////////////////////////////////////////////////////////////////////////
5129/// Allows to copy file from src to dst URL. Returns kTRUE in case of success,
5130/// kFALSE otherwise.
5132Bool_t TFile::Cp(const char *src, const char *dst, Bool_t progressbar,
5133 UInt_t buffersize)
5134{
5135 TUrl sURL(src, kTRUE);
5136
5137 // Files will be open in RAW mode
5138 TString raw = "filetype=raw";
5139
5140 // Set optimization options for the source file
5141 TString opt = sURL.GetOptions();
5142 if (opt != "") opt += "&";
5143 opt += raw;
5144 // Netx-related options:
5145 // cachesz = 4*buffersize -> 4 buffers as peak mem usage
5146 // readaheadsz = 2*buffersize -> Keep at max 4*buffersize bytes outstanding when reading
5147 // rmpolicy = 1 -> Remove from the cache the blk with the least offset
5148 opt += TString::Format("&cachesz=%d&readaheadsz=%d&rmpolicy=1", 4*buffersize, 2*buffersize);
5149 sURL.SetOptions(opt);
5150
5151 TFile *sfile = nullptr;
5152
5153 Bool_t success = kFALSE;
5154
5155 // Open source file
5156 if (!(sfile = TFile::Open(sURL.GetUrl(), "READ"))) {
5157 ::Error("TFile::Cp", "cannot open source file %s", src);
5158 } else {
5159 success = sfile->Cp(dst, progressbar, buffersize);
5160 }
5161
5162 if (sfile) {
5163 sfile->Close();
5164 delete sfile;
5165 }
5166
5167 return success;
5168}
5169
5170//______________________________________________________________________________
5171//The next statement is not active anymore on Linux.
5172//Using posix_fadvise introduces a performance penalty (10 %) on optimized files
5173//and in addition it destroys the information of TTreePerfStats
5174#if defined(R__neverLINUX) && !defined(R__WINGCC)
5176{
5177 // Read specified byte range asynchronously. Actually we tell the kernel
5178 // which blocks we are going to read so it can start loading these blocks
5179 // in the buffer cache.
5180
5181 // Shortcut to avoid having to implement dummy ReadBufferAsync() in all
5182 // I/O plugins. Override ReadBufferAsync() in plugins if async is supported.
5183 if (IsA() != TFile::Class())
5184 return kTRUE;
5185
5186 int advice = POSIX_FADV_WILLNEED;
5187 if (len == 0) {
5188 // according POSIX spec if len is zero, all data following offset
5189 // is specified. Nevertheless ROOT uses zero to probe readahead
5190 // capabilities.
5191 advice = POSIX_FADV_NORMAL;
5192 }
5193 Double_t start = 0;
5194 if (gPerfStats) start = TTimeStamp();
5195#if defined(R__SEEK64)
5196 Int_t result = posix_fadvise64(fD, offset, len, advice);
5197#else
5198 Int_t result = posix_fadvise(fD, offset, len, advice);
5199#endif
5200 if (gPerfStats) {
5201 gPerfStats->FileReadEvent(this, len, start);
5202 }
5203 return (result != 0);
5204}
5205#else
5207{
5208 // Not supported yet on non Linux systems.
5209
5210 return kTRUE;
5211}
5212#endif
5213
5214////////////////////////////////////////////////////////////////////////////////
5215/// Max number of bytes to prefetch.
5216///
5217/// By default this is 75% of the
5218/// read cache size. But specific TFile implementations may need to change it
5221{
5222 TFileCacheRead *cr = nullptr;
5223 if ((cr = GetCacheRead())) {
5224 Int_t bytes = cr->GetBufferSize() / 4 * 3;
5225 return ((bytes < 0) ? 0 : bytes);
5226 }
5227 return 0;
5228}
void frombuf(char *&buf, Bool_t *x)
Definition Bytes.h:278
void tobuf(char *&buf, Bool_t x)
Definition Bytes.h:55
#define SafeDelete(p)
Definition RConfig.hxx:533
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define h(i)
Definition RSha256.hxx:106
static void update(gsl_integration_workspace *workspace, double a1, double b1, double area1, double error1, double a2, double b2, double area2, double error2)
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
short Version_t
Definition RtypesCore.h:65
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:117
long long Long64_t
Definition RtypesCore.h:69
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:382
#define gDirectory
Definition TDirectory.h:384
R__EXTERN TEnv * gEnv
Definition TEnv.h:170
const Int_t kBEGIN
Definition TFile.cxx:180
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t attr
Option_t Option_t TPoint TPoint const char mode
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t bytes
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:110
#define gInterpreter
R__EXTERN TPluginManager * gPluginMgr
Int_t gDebug
Definition TROOT.cxx:597
R__EXTERN TVirtualMutex * gROOTMutex
Definition TROOT.h:63
#define gROOT
Definition TROOT.h:406
void Printf(const char *fmt,...)
Formats a string in a circular formatting buffer and prints the string.
Definition TString.cxx:2503
@ kFileExists
Definition TSystem.h:42
@ kReadPermission
Definition TSystem.h:45
@ kWritePermission
Definition TSystem.h:44
Bool_t R_ISDIR(Int_t mode)
Definition TSystem.h:113
R__EXTERN TSystem * gSystem
Definition TSystem.h:561
R__EXTERN void **(* gThreadTsd)(void *, Int_t)
R__EXTERN TVirtualMonitoringWriter * gMonitoringWriter
#define R__LOCKGUARD(mutex)
#define gPerfStats
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
#define O_BINARY
Definition civetweb.c:912
#define snprintf
Definition civetweb.c:1540
const TMatches FindRules(const TString &source) const
Return all the rules that are about the given 'source' class.
const TObjArray * GetRules() const
This class is a thread-safe associative collection connecting a 256 bits digest/hash to a collection ...
bool Insert(const HashValue &hash, RUidColl &&coll) const
If the hash is there, return false.
static HashValue Hash(char *buf, int len)
Return the hash object corresponding to the buffer.
const RUidColl * Find(const HashValue &hash) const
Return the collection of UID corresponding to the hash if the hash has already been seen or nullptr o...
void AsString(TString &out, const char *options="") const
Add to the string 'out' the string representation of the rule.
const char * GetMemberName() const
virtual Int_t SetCurrentMember()=0
const char * GetArchiveName() const
TArchiveMember * GetMember() const
static TArchiveFile * Open(const char *url, TFile *file)
Return proper archive file handler depending on passed url.
Long64_t GetMemberFilePosition() const
Return position in archive of current member.
virtual Int_t OpenArchive()=0
Long64_t GetDecompressedSize() const
Array of chars or bytes (8 bits per element).
Definition TArrayC.h:27
Char_t * fArray
Definition TArrayC.h:30
void Set(Int_t n) override
Set size of this array to n chars.
Definition TArrayC.cxx:105
Int_t GetSize() const
Definition TArray.h:47
Buffer base class used for serializing objects.
Definition TBuffer.h:43
@ kInitialSize
Definition TBuffer.h:78
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
Bool_t IsSyntheticPair() const
Definition TClass.h:522
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition TClass.cxx:2955
Bool_t HasInterpreterInfo() const
Definition TClass.h:411
const ROOT::Detail::TSchemaRuleSet * GetSchemaRules() const
Return the set of the schema rules if any.
Definition TClass.cxx:2001
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5993
static Bool_t AddRule(const char *rule)
Add a schema evolution customization rule.
Definition TClass.cxx:1959
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4943
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2966
Version_t GetClassVersion() const
Definition TClass.h:421
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:3037
virtual bool UseRWLock(Bool_t enable=true)
Set this collection to use a RW lock upon access, making it thread safe.
void ls(Option_t *option="") const override
List (ls) all objects in this collection.
void SetName(const char *name)
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TObject * Clone(const char *newname="") const override
Make a clone of an collection using the Streamer facility.
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
static void GetDateTime(UInt_t datetime, Int_t &date, Int_t &time)
Static function that returns the date and time.
Definition TDatime.cxx:431
void ReadBuffer(char *&buffer)
Decode Date/Time from output buffer, used by I/O system.
Definition TDatime.cxx:278
A ROOT file is structured in Directories (like a file system).
void Close(Option_t *option="") override
Delete all objects from memory and directory structure itself.
Bool_t cd() override
Change current directory to "this" directory.
Bool_t IsWritable() const override
void Delete(const char *namecycle="") override
Delete Objects or/and keys in a directory.
Int_t AppendKey(TKey *key) override
Insert key in the linked list of keys of this directory.
Int_t ReadKeys(Bool_t forceRead=kTRUE) override
Read the linked list of keys.
TDatime fDatimeM
Date and time of last modification.
void Save() override
Save recursively all directory keys and headers.
Int_t fNbytesKeys
Number of bytes for the keys.
Int_t GetNkeys() const override
Long64_t fSeekKeys
Location of Keys record on file.
Int_t Sizeof() const override
Return the size in bytes of the directory header.
Long64_t fSeekParent
Location of parent directory on file.
void BuildDirectoryFile(TFile *motherFile, TDirectory *motherDir)
Initialise directory to defaults.
Int_t Write(const char *name=nullptr, Int_t opt=0, Int_t bufsize=0) override
Write all objects in memory to disk.
Long64_t fSeekDir
Location of directory on file.
Int_t fNbytesName
Number of bytes in TNamed at creation time.
TDatime fDatimeC
Date and time when directory is created.
Bool_t fWritable
True if directory is writable.
Int_t WriteTObject(const TObject *obj, const char *name=nullptr, Option_t *option="", Int_t bufsize=0) override
Write object obj to this directory.
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
void FillBuffer(char *&buffer) override
Encode directory header into output buffer.
void SetWritable(Bool_t writable=kTRUE) override
Set the new value of fWritable recursively.
TList * fKeys
Pointer to keys list in memory.
void ls(Option_t *option="") const override
List Directory contents.
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
Describe directory structure in memory.
Definition TDirectory.h:45
virtual TList * GetList() const
Definition TDirectory.h:222
void SetName(const char *newname) override
Set the name for directory If the directory name is changed after the directory was written once,...
TUUID fUUID
Definition TDirectory.h:143
TList * fList
Definition TDirectory.h:142
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:491
A cache when reading files over the network.
virtual Int_t ReadBuffer(char *buf, Long64_t pos, Int_t len)
Read buffer at position pos.
virtual void Close(Option_t *option="")
Close out any threads or asynchronous fetches used by the underlying implementation.
virtual Int_t GetBufferSize() const
TFile * GetFile() const
virtual void SetFile(TFile *file, TFile::ECacheAction action=TFile::kDisconnect)
Set the file using this cache and reset the current blocks (if any).
A cache when writing files over the network.
virtual Bool_t Flush()
Flush the current write buffer to the file.
virtual Int_t ReadBuffer(char *buf, Long64_t pos, Int_t len)
Called by the read cache to check if the requested data is not in the write cache buffer.
virtual Int_t GetBytesInCache() const
virtual Int_t WriteBuffer(const char *buf, Long64_t pos, Int_t len)
Write buffer at position pos in the write buffer.
Class holding info about the file being opened.
Definition TFile.h:354
TFile * fFile
TFile instance of the file being opened.
Definition TFile.h:362
Int_t GetNetOpt() const
Definition TFile.h:381
TFile * GetFile() const
Definition TFile.h:372
const char * GetOpt() const
Definition TFile.h:379
Bool_t Matches(const char *name)
Return kTRUE if this async request matches the open request specified by 'url'.
Definition TFile.cxx:4787
Int_t GetCompress() const
Definition TFile.h:380
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:53
static std::atomic< Long64_t > fgBytesRead
Number of bytes read by all TFile objects.
Definition TFile.h:131
Int_t fReadCalls
Number of read calls ( not counting the cache calls )
Definition TFile.h:89
static void SetFileBytesWritten(Long64_t bytes=0)
Definition TFile.cxx:4608
static Bool_t fgCacheFileForce
Indicates, to force all READ to CACHEREAD.
Definition TFile.h:126
Long64_t fBytesRead
Number of bytes read from this file.
Definition TFile.h:76
virtual TProcessID * ReadProcessID(UShort_t pidf)
The TProcessID with number pidf is read from this file.
Definition TFile.cxx:1948
void ls(Option_t *option="") const override
List file contents.
Definition TFile.cxx:1454
virtual void Seek(Long64_t offset, ERelativeTo pos=kBeg)
Seek to a specific position in the file. Pos it either kBeg, kCur or kEnd.
Definition TFile.cxx:2271
static Bool_t GetOnlyStaged()
Returns staged only flag.
Definition TFile.cxx:4751
static void IncrementFileCounter()
Definition TFile.cxx:4617
static Bool_t ShrinkCacheFileDir(Long64_t shrinkSize, Long_t cleanupInteval=0)
Try to shrink the cache to the desired size.
Definition TFile.cxx:4663
Long64_t fSeekFree
Location on disk of free segments structure.
Definition TFile.h:80
static Int_t fgReadaheadSize
Readahead buffer size.
Definition TFile.h:134
void FillBuffer(char *&buffer) override
Encode file output buffer.
Definition TFile.cxx:1167
Double_t fSum2Buffer
Sum of squares of buffer sizes of objects written so far.
Definition TFile.h:74
static void SetReadaheadSize(Int_t bufsize=256000)
Definition TFile.cxx:4602
static Bool_t fgCacheFileDisconnected
Indicates, we trust in the files in the cache dir without stat on the cached file.
Definition TFile.h:125
const TList * GetStreamerInfoCache()
Returns the cached list of StreamerInfos used in this file.
Definition TFile.cxx:1363
static Bool_t GetReadStreamerInfo()
If the streamerinfos are to be read at file opening.
Definition TFile.cxx:3739
TArchiveFile * fArchive
!Archive file from which we read this file
Definition TFile.h:97
virtual Int_t SysSync(Int_t fd)
Interface to system fsync. All arguments like in POSIX fsync().
Definition TFile.cxx:4549
static TClass * Class()
virtual Int_t ReOpen(Option_t *mode)
Reopen a file with a different access mode.
Definition TFile.cxx:2159
virtual void ReadStreamerInfo()
Read the list of StreamerInfo from this file.
Definition TFile.cxx:3602
virtual Bool_t Matches(const char *name)
Return kTRUE if 'url' matches the coordinates of this file.
Definition TFile.cxx:4763
virtual void SetCacheRead(TFileCacheRead *cache, TObject *tree=nullptr, ECacheAction action=kDisconnect)
Set a pointer to the read cache.
Definition TFile.cxx:2362
TArrayC * fClassIndex
!Index of TStreamerInfo classes written to this file
Definition TFile.h:94
static Long64_t GetFileBytesWritten()
Static function returning the total number of bytes written to all files.
Definition TFile.cxx:4580
virtual InfoListRet GetStreamerInfoListImpl(bool lookupSICache)
See documentation of GetStreamerInfoList for more details.
Definition TFile.cxx:1373
@ kStartBigFile
Definition TFile.h:200
static void SetReadStreamerInfo(Bool_t readinfo=kTRUE)
Specify if the streamerinfos must be read at file opening.
Definition TFile.cxx:3729
Bool_t fNoAnchorInName
!True if we don't want to force the anchor to be appended to the file name
Definition TFile.h:103
static void SetFileBytesRead(Long64_t bytes=0)
Definition TFile.cxx:4605
Long64_t fSeekInfo
Location on disk of StreamerInfo record.
Definition TFile.h:81
void Paint(Option_t *option="") override
Paint all objects in the file.
Definition TFile.cxx:1695
Int_t GetBestBuffer() const
Return the best buffer size of objects on this file.
Definition TFile.cxx:1180
TList * fOpenPhases
!Time info about open phases
Definition TFile.h:113
virtual void SetCompressionLevel(Int_t level=ROOT::RCompressionSetting::ELevel::kUseMin)
See comments for function SetCompressionSettings.
Definition TFile.cxx:2316
TFileCacheWrite * GetCacheWrite() const
Return a pointer to the current write cache.
Definition TFile.cxx:1276
static void SetFileReadCalls(Int_t readcalls=0)
Definition TFile.cxx:4611
static TString fgCacheFileDir
Directory where to locally stage files.
Definition TFile.h:124
virtual Int_t SysRead(Int_t fd, void *buf, Int_t len)
Interface to system read. All arguments like in POSIX read().
Definition TFile.cxx:4503
Int_t fVersion
File format version.
Definition TFile.h:83
void Print(Option_t *option="") const override
Print all objects in the file.
Definition TFile.cxx:1703
static std::atomic< Long64_t > fgFileCounter
Counter for all opened files.
Definition TFile.h:132
virtual EAsyncOpenStatus GetAsyncOpenStatus()
Definition TFile.h:137
void Streamer(TBuffer &) override
Stream a TFile object.
Definition TFile.cxx:2402
static UInt_t GetOpenTimeout()
Returns open timeout (in ms).
Definition TFile.cxx:4731
static void CpProgress(Long64_t bytesread, Long64_t size, TStopwatch &watch)
Print file copy progress.
Definition TFile.cxx:4972
static Bool_t fgOnlyStaged
Before the file is opened, it is checked, that the file is staged, if not, the open fails.
Definition TFile.h:128
virtual Int_t GetNProcessIDs() const
Definition TFile.h:239
Bool_t fMustFlush
!True if the file buffers must be flushed
Definition TFile.h:106
TUrl fUrl
!URL of file
Definition TFile.h:110
Int_t WriteBufferViaCache(const char *buf, Int_t len)
Write buffer via cache.
Definition TFile.cxx:2516
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition TFile.cxx:4571
Int_t ReadBufferViaCache(char *buf, Int_t len)
Read buffer via cache.
Definition TFile.cxx:1886
virtual TKey * CreateKey(TDirectory *mother, const TObject *obj, const char *name, Int_t bufsize)
Creates key for object and converts data to buffer.
Definition TFile.cxx:1044
virtual void Map()
Definition TFile.h:267
virtual void WriteFree()
Write FREE linked list on the file.
Definition TFile.cxx:2540
static Int_t GetReadaheadSize()
Static function returning the readahead buffer size.
Definition TFile.cxx:4596
~TFile() override
File destructor.
Definition TFile.cxx:560
virtual Bool_t ReadBuffers(char *buf, Long64_t *pos, Int_t *len, Int_t nbuf)
Read the nbuf blocks described in arrays pos and len.
Definition TFile.cxx:1818
static Long64_t GetFileCounter()
Definition TFile.cxx:4614
TMap * fCacheReadMap
!Pointer to the read cache (if any)
Definition TFile.h:99
Long64_t fBEGIN
First used byte in file.
Definition TFile.h:78
Int_t MakeProjectParProofInf(const char *packname, const char *proofinfdir)
Create BUILD.sh and SETUP.C under 'proofinf' for PAR package 'pack'.
Definition TFile.cxx:3483
virtual UShort_t WriteProcessID(TProcessID *pid)
Check if the ProcessID pidd is already in the file, if not, add it and return the index number in the...
Definition TFile.cxx:3760
virtual void MakeProject(const char *dirname, const char *classes="*", Option_t *option="new")
Generate source code necessary to access the objects stored in the file.
Definition TFile.cxx:2723
Long64_t fArchiveOffset
!Offset at which file starts in archive
Definition TFile.h:101
@ kEternalTimeout
Definition TFile.h:67
Int_t fNbytesInfo
Number of bytes for StreamerInfo record.
Definition TFile.h:86
virtual Long64_t GetSize() const
Returns the current file size.
Definition TFile.cxx:1344
virtual Bool_t IsOpen() const
Returns kTRUE in case file is open and kFALSE if file is not open.
Definition TFile.cxx:1466
TFileOpenHandle * fAsyncHandle
!For proper automatic cleanup
Definition TFile.h:108
static Bool_t SetOnlyStaged(Bool_t onlystaged)
Sets only staged flag.
Definition TFile.cxx:4741
virtual Long64_t GetBytesRead() const
Definition TFile.h:241
virtual Int_t GetErrno() const
Method returning errno.
Definition TFile.cxx:1243
virtual void SetCompressionSettings(Int_t settings=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault)
Used to specify the compression level and algorithm.
Definition TFile.cxx:2335
static Bool_t fgReadInfo
if true (default) ReadStreamerInfo is called when opening a file
Definition TFile.h:135
virtual void Init(Bool_t create)
Initialize a TFile object.
Definition TFile.cxx:610
Long64_t GetRelOffset() const
Definition TFile.h:251
static TFileOpenHandle * AsyncOpen(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Submit an asynchronous open request.
Definition TFile.cxx:4348
virtual void SetCacheWrite(TFileCacheWrite *cache)
Set a pointer to the write cache.
Definition TFile.cxx:2385
TString fOption
File options.
Definition TFile.h:91
virtual Bool_t WriteBuffer(const char *buf, Int_t len)
Write a buffer to the file.
Definition TFile.cxx:2473
void SumBuffer(Int_t bufsize)
Increment statistics for buffer sizes of objects in this file.
Definition TFile.cxx:2414
static const char * GetCacheFileDir()
Get the directory where to locally stage/cache remote files.
Definition TFile.cxx:4651
EAsyncOpenStatus
Asynchronous open request status.
Definition TFile.h:64
@ kAOSSuccess
Definition TFile.h:65
@ kAOSNotAsync
Definition TFile.h:64
@ kAOSInProgress
Definition TFile.h:65
@ kAOSFailure
Definition TFile.h:64
virtual void WriteStreamerInfo()
Write the list of TStreamerInfo as a single object in this file The class Streamer description for al...
Definition TFile.cxx:3789
virtual Long64_t GetBytesWritten() const
Return the total number of bytes written so far to the file.
Definition TFile.cxx:4563
ERelativeTo
Definition TFile.h:199
@ kCur
Definition TFile.h:199
@ kBeg
Definition TFile.h:199
@ kEnd
Definition TFile.h:199
Int_t fCompress
Compression level and algorithm.
Definition TFile.h:84
static TFile *& CurrentFile()
Return the current ROOT file if any.
Definition TFile.cxx:1064
virtual void SetCompressionAlgorithm(Int_t algorithm=ROOT::RCompressionSetting::EAlgorithm::kUseGlobal)
See comments for function SetCompressionSettings.
Definition TFile.cxx:2302
virtual const TUrl * GetEndpointUrl() const
Definition TFile.h:235
Int_t fNbytesFree
Number of bytes for free segments structure.
Definition TFile.h:85
Int_t fD
File descriptor.
Definition TFile.h:82
static constexpr Version_t Class_Version()
Definition TFile.h:344
virtual void ResetErrno() const
Method resetting the errno.
Definition TFile.cxx:1251
Int_t Sizeof() const override
Return the size in bytes of the file header.
Definition TFile.cxx:2394
Bool_t FlushWriteCache()
Flush the write cache if active.
Definition TFile.cxx:1155
virtual void IncrementProcessIDs()
Definition TFile.h:257
Bool_t fIsPcmFile
!True if the file is a ROOT pcm file.
Definition TFile.h:107
TFileCacheRead * fCacheRead
!Pointer to the read cache (if any)
Definition TFile.h:98
virtual Int_t SysClose(Int_t fd)
Interface to system close. All arguments like in POSIX close().
Definition TFile.cxx:4494
TFile()
File default Constructor.
Definition TFile.cxx:198
Char_t fUnits
Number of bytes for file pointers.
Definition TFile.h:92
TObjArray * fProcessIDs
!Array of pointers to TProcessIDs
Definition TFile.h:95
static EFileType GetType(const char *name, Option_t *option="", TString *prefix=nullptr)
Resolve the file type as a function of the protocol field in 'name'.
Definition TFile.cxx:4818
EFileType
File type.
Definition TFile.h:202
@ kWeb
Definition TFile.h:202
@ kDefault
Definition TFile.h:202
@ kLocal
Definition TFile.h:202
@ kMerge
Definition TFile.h:202
@ kNet
Definition TFile.h:202
@ kFile
Definition TFile.h:202
virtual void ShowStreamerInfo()
Show the StreamerInfo of all classes written to this file.
Definition TFile.cxx:3747
virtual Long64_t SysSeek(Int_t fd, Long64_t offset, Int_t whence)
Interface to system lseek.
Definition TFile.cxx:4522
virtual Int_t SysStat(Int_t fd, Long_t *id, Long64_t *size, Long_t *flags, Long_t *modtime)
Return file stat information.
Definition TFile.cxx:4540
virtual Int_t SysOpen(const char *pathname, Int_t flags, UInt_t mode)
Interface to system open. All arguments like in POSIX open().
Definition TFile.cxx:4478
ECacheAction
TTreeCache flushing semantics.
Definition TFile.h:70
@ kDoNotDisconnect
Definition TFile.h:70
static UInt_t SetOpenTimeout(UInt_t timeout)
Sets open timeout time (in ms). Returns previous timeout value.
Definition TFile.cxx:4721
virtual void ReadFree()
Read the FREE linked list.
Definition TFile.cxx:1922
virtual Bool_t Cp(const char *dst, Bool_t progressbar=kTRUE, UInt_t buffersize=1000000)
Allows to copy this file to the dst URL.
Definition TFile.cxx:5000
static ROOT::Internal::RConcurrentHashColl fgTsSIHashes
!TS Set of hashes built from read streamer infos
Definition TFile.h:120
Long64_t fBytesReadExtra
Number of extra bytes (overhead) read by the readahead buffer.
Definition TFile.h:77
Long64_t fBytesWrite
Number of bytes written to this file.
Definition TFile.h:75
Bool_t fIsRootFile
!True is this is a ROOT file, raw file otherwise
Definition TFile.h:104
virtual void Flush()
Synchronize a file's in-memory and on-disk states.
Definition TFile.cxx:1138
TList * fFree
Free segments linked list table.
Definition TFile.h:93
virtual Bool_t ReadBufferAsync(Long64_t offs, Int_t len)
Definition TFile.cxx:5205
void Delete(const char *namecycle="") override
Delete object namecycle.
Definition TFile.cxx:1095
Bool_t fInitDone
!True if the file has been initialized
Definition TFile.h:105
virtual void DrawMap(const char *keys="*", Option_t *option="")
Draw map of objects in this file.
Definition TFile.cxx:1125
virtual void MakeFree(Long64_t first, Long64_t last)
Mark unused bytes on the file.
Definition TFile.cxx:1481
TFileCacheWrite * fCacheWrite
!Pointer to the write cache (if any)
Definition TFile.h:100
TString fRealName
Effective real file name (not original url)
Definition TFile.h:90
virtual void SetOffset(Long64_t offset, ERelativeTo pos=kBeg)
Set position from where to start reading.
Definition TFile.cxx:2250
Long64_t fOffset
!Seek offset cache
Definition TFile.h:96
static std::atomic< Long64_t > fgBytesWrite
Number of bytes written by all TFile objects.
Definition TFile.h:130
TList * fInfoCache
!Cached list of the streamer infos in this file
Definition TFile.h:112
virtual Int_t GetBytesToPrefetch() const
Max number of bytes to prefetch.
Definition TFile.cxx:5219
static UInt_t fgOpenTimeout
Timeout for open operations in ms - 0 corresponds to blocking i/o.
Definition TFile.h:127
Int_t MakeProjectParMake(const char *packname, const char *filename)
Create makefile at 'filemake' for PAR package 'pack'.
Definition TFile.cxx:3361
Long64_t fEND
Last used byte in file.
Definition TFile.h:79
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:4086
static Bool_t SetCacheFileDir(std::string_view cacheDir, Bool_t operateDisconnected=kTRUE, Bool_t forceCacheread=kFALSE)
Sets the directory where to locally stage/cache remote files.
Definition TFile.cxx:4623
Int_t Write(const char *name=nullptr, Int_t opt=0, Int_t bufsiz=0) override
Write memory objects to this file.
Definition TFile.cxx:2433
EAsyncOpenStatus fAsyncOpenStatus
!Status of an asynchronous open request
Definition TFile.h:109
bool fGlobalRegistration
! if true, bypass use of global lists
Definition TFile.h:115
Double_t fSumBuffer
Sum of buffer sizes of objects written so far.
Definition TFile.h:73
Bool_t fIsArchive
!True if this is a pure archive file
Definition TFile.h:102
TObjArray * GetListOfProcessIDs() const
Definition TFile.h:236
void Draw(Option_t *option="") override
Fill Graphics Structure and Paint.
Definition TFile.cxx:1108
void Close(Option_t *option="") override
Close a file.
Definition TFile.cxx:947
TClass * IsA() const override
Definition TFile.h:344
static std::atomic< Int_t > fgReadCalls
Number of bytes read from all TFile objects.
Definition TFile.h:133
virtual Int_t Recover()
Attempt to recover file if not correctly closed.
Definition TFile.cxx:2045
virtual TList * GetStreamerInfoList() final
Read the list of TStreamerInfo objects written to this file.
Definition TFile.cxx:1442
virtual void WriteHeader()
Write File Header.
Definition TFile.cxx:2612
@ kRecovered
Definition TFile.h:191
@ kReproducible
Definition TFile.h:197
@ kDevNull
Definition TFile.h:193
@ kHasReferences
Definition TFile.h:192
@ k630forwardCompatibility
Definition TFile.h:190
@ kWriteError
Definition TFile.h:194
@ kBinaryFile
Definition TFile.h:195
static TFile * OpenFromCache(const char *name, Option_t *="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Open a file for reading through the file cache.
Definition TFile.cxx:3871
Int_t fNProcessIDs
Number of TProcessID written to this file.
Definition TFile.h:88
Int_t fWritten
Number of objects written so far.
Definition TFile.h:87
Int_t GetRecordHeader(char *buf, Long64_t first, Int_t maxbytes, Int_t &nbytes, Int_t &objlen, Int_t &keylen)
Read the logical record header starting at a certain postion.
Definition TFile.cxx:1298
virtual Bool_t ReadBuffer(char *buf, Int_t len)
Read a buffer from the file.
Definition TFile.cxx:1767
Float_t GetCompressionFactor()
Return the file compression factor.
Definition TFile.cxx:1199
virtual Int_t SysWrite(Int_t fd, const void *buf, Int_t len)
Interface to system write. All arguments like in POSIX write().
Definition TFile.cxx:4511
static Int_t GetFileReadCalls()
Static function returning the total number of read calls from all files.
Definition TFile.cxx:4588
TFileCacheRead * GetCacheRead(const TObject *tree=nullptr) const
Return a pointer to the current read cache.
Definition TFile.cxx:1259
Option_t * GetOption() const override
Definition TFile.h:240
static TList * fgAsyncOpenRequests
Definition TFile.h:122
Service class for TFile.
Definition TFree.h:27
Long64_t GetLast() const
Definition TFree.h:41
Int_t Sizeof() const
return number of bytes occupied by this TFree on permanent storage
Definition TFree.cxx:184
virtual void ReadBuffer(char *&buffer)
Decode one free structure from input buffer.
Definition TFree.cxx:167
Long64_t GetFirst() const
Definition TFree.h:40
virtual void FillBuffer(char *&buffer)
Encode fre structure into output buffer.
Definition TFree.cxx:109
TFree * AddFree(TList *lfree, Long64_t first, Long64_t last)
Add a new free segment to the list of free segments.
Definition TFree.cxx:67
static void MakeFunctor(const char *name, const char *type, GlobFunc &func)
Definition TGlobal.h:73
void Reset()
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
void Delete(Option_t *option="") override
Delete an object from the file.
Definition TKey.cxx:538
virtual Long64_t GetSeekKey() const
Definition TKey.h:89
Int_t GetKeylen() const
Definition TKey.h:84
Int_t GetObjlen() const
Definition TKey.h:87
Int_t GetNbytes() const
Definition TKey.h:86
virtual const char * GetClassName() const
Definition TKey.h:75
virtual Bool_t ReadFile()
Read the key structure from the file.
Definition TKey.cxx:1273
void ReadKeyBuffer(char *&buffer)
Decode input buffer.
Definition TKey.cxx:1230
virtual Int_t WriteFile(Int_t cycle=1, TFile *f=nullptr)
Write the encoded object supported by this key.
Definition TKey.cxx:1455
virtual char * GetBuffer() const
Definition TKey.h:78
A doubly linked list.
Definition TList.h:38
void AddAfter(const TObject *after, TObject *obj) override
Insert object after object after in the list.
Definition TList.cxx:248
void Clear(Option_t *option="") override
Remove all objects from the list.
Definition TList.cxx:400
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:576
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:820
TObject * Last() const override
Return the last object in the list. Returns 0 when list is empty.
Definition TList.cxx:691
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:657
virtual TObjLink * FirstLink() const
Definition TList.h:102
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
void RemoveLast() override
Remove the last object of the list.
Definition TList.cxx:907
static void GenerateMissingStreamerInfos(TList *extrainfos, TStreamerElement *element)
Generate an empty StreamerInfo for types that are used in templates parameters but are not known in t...
static TString UpdateAssociativeToVector(const char *name)
TMap implements an associative array of (key,value) pairs using a THashTable for efficient retrieval ...
Definition TMap.h:40
void Add(TObject *obj) override
This function may not be used (but we need to provide it since it is a pure virtual in TCollection).
Definition TMap.cxx:54
TObject * Remove(TObject *key) override
Remove the (key,value) pair with key from the map.
Definition TMap.cxx:296
TObject * GetValue(const char *keyname) const
Returns a pointer to the value associated with keyname as name of the key.
Definition TMap.cxx:236
virtual void FillBuffer(char *&buffer)
Encode TNamed into output buffer.
Definition TNamed.cxx:104
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:164
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
virtual Int_t Sizeof() const
Return size of the TNamed part of the TObject.
Definition TNamed.cxx:173
Iterator of object array.
Definition TObjArray.h:117
TObject * Next() override
Return next object in array. Returns 0 when no more objects in array.
An array of TObjects.
Definition TObjArray.h:31
Int_t IndexOf(const TObject *obj) const override
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:84
void Add(TObject *obj) override
Definition TObjArray.h:68
Collectable string class.
Definition TObjString.h:28
TString & String()
Definition TObjString.h:48
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:456
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:474
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition TObject.cxx:1019
R__ALWAYS_INLINE Bool_t IsOnHeap() const
Definition TObject.h:152
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:225
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:991
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:153
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:798
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1005
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1033
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:809
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:500
void MakeZombie()
Definition TObject.h:53
void ResetBit(UInt_t f)
Definition TObject.h:198
@ kCanDelete
if object in a list can be deleted
Definition TObject.h:62
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:979
Wrapper for PCRE library (Perl Compatible Regular Expressions).
Definition TPRegexp.h:97
Int_t Match(const TString &s, UInt_t start=0)
Runs a match on s against the regex 'this' was created with.
Definition TPRegexp.cxx:797
Longptr_t ExecPlugin(int nargs)
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition TProcessID.h:74
Int_t IncrementCount()
Increase the reference count to this object.
void Clear(Option_t *option="") override
delete the TObjArray pointing to referenced objects this function is called by TFile::Close("R")
void CheckInit()
Initialize fObjects.
static TObjArray * GetPIDs()
static: returns array of TProcessIDs
static TProcessID * GetSessionProcessID()
static function returning the pointer to the session TProcessID
Int_t DecrementCount()
The reference fCount is used to delete the TProcessID in the TFile destructor when fCount = 0.
static TProcessID * GetPID()
static: returns pointer to current TProcessID
static Int_t IncreaseDirLevel()
Increase the indentation level for ls().
Definition TROOT.cxx:2887
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition TROOT.cxx:2895
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3056
static Int_t DecreaseDirLevel()
Decrease the indentation level for ls().
Definition TROOT.cxx:2746
Sequenceable collection abstract base class.
Stopwatch class.
Definition TStopwatch.h:28
Double_t RealTime()
Stop the stopwatch (if it is running) and return the realtime (in seconds) passed between the start a...
void Start(Bool_t reset=kTRUE)
Start the stopwatch.
void Continue()
Resume a stopped stopwatch.
void Stop()
Stop the stopwatch.
void Reset()
Definition TStopwatch.h:52
UInt_t GetBaseCheckSum()
void SetBaseCheckSum(UInt_t cs)
TClass * GetClass() const
Describes a persistent version of a class.
Int_t GetClassVersion() const override
Int_t GenerateHeaderFile(const char *dirname, const TList *subClasses=nullptr, const TList *extrainfos=nullptr) override
Generate header file for the class described by this TStreamerInfo the function is called by TFile::M...
Int_t GetNumber() const override
TClass * IsA() const override
TClass * GetClass() const override
TObjArray * GetElements() const override
UInt_t GetCheckSum() const override
void BuildCheck(TFile *file=nullptr, Bool_t load=kTRUE) override
Check if built and consistent with the class dictionary.
static TClass * Class()
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition TString.cxx:457
TString & Insert(Ssiz_t pos, const char *s)
Definition TString.h:661
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1988
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition TString.cxx:2244
void Clear()
Clear string without changing its capacity.
Definition TString.cxx:1235
const char * Data() const
Definition TString.h:376
Bool_t IsDigit() const
Returns true if all characters in string are digits (0-9) or white spaces, i.e.
Definition TString.cxx:1830
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
@ kIgnoreCase
Definition TString.h:277
void ToUpper()
Change string to upper case.
Definition TString.cxx:1195
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition TString.cxx:2264
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:623
Bool_t IsNull() const
Definition TString.h:414
TString & Remove(Ssiz_t pos)
Definition TString.h:685
TString & Append(const char *cs)
Definition TString.h:572
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2378
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition TString.cxx:2356
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
virtual void ReadBuffer(char *&buffer)
Read string from I/O buffer.
Definition TString.cxx:1331
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
virtual FILE * TempFileName(TString &base, const char *dir=nullptr, const char *suffix=nullptr)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition TSystem.cxx:1499
virtual const char * GetMakeSharedLib() const
Return the command line use to make a shared library.
Definition TSystem.cxx:3956
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=nullptr)
Redirect standard output (stdout, stderr) to the specified file.
Definition TSystem.cxx:1715
virtual void IgnoreInterrupt(Bool_t ignore=kTRUE)
If ignore is true ignore the interrupt signal, else restore previous behaviour.
Definition TSystem.cxx:602
virtual int Symlink(const char *from, const char *to)
Create a symbolic link from file1 to file2.
Definition TSystem.cxx:1368
static void ResetErrno()
Static function resetting system error number.
Definition TSystem.cxx:284
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1274
static Int_t GetErrno()
Static function returning system error number.
Definition TSystem.cxx:276
virtual int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Definition TSystem.cxx:1508
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition TSystem.cxx:845
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition TSystem.cxx:836
virtual int GetPid()
Get process id.
Definition TSystem.cxx:707
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition TSystem.cxx:1341
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:3973
virtual void ShowOutput(RedirectHandle_t *h)
Display the content associated with the redirection described by the opaque handle 'h'.
Definition TSystem.cxx:1725
virtual Bool_t IsPathLocal(const char *path)
Returns TRUE if the url in 'path' points to the local file system.
Definition TSystem.cxx:1305
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition TSystem.cxx:906
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition TSystem.cxx:653
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1857
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1398
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1081
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:1296
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition TSystem.cxx:853
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition TSystem.cxx:862
virtual int Rename(const char *from, const char *to)
Rename a file.
Definition TSystem.cxx:1350
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:934
virtual const char * GetFlagsDebug() const
Return the debug flags.
Definition TSystem.cxx:3927
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition TSystem.cxx:951
virtual const char * GetObjExt() const
Get the object file extension.
Definition TSystem.cxx:4021
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition TSystem.cxx:437
virtual const char * WorkingDirectory()
Return working directory.
Definition TSystem.cxx:871
virtual const char * GetLibraries(const char *regexp="", const char *option="", Bool_t isRegexp=kTRUE)
Return a space separated list of loaded shared libraries.
Definition TSystem.cxx:2136
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:887
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition TSystem.cxx:416
virtual const char * GetSoExt() const
Get the shared library extension.
Definition TSystem.cxx:4013
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1032
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1381
virtual const char * GetFlagsOpt() const
Return the optimization flags.
Definition TSystem.cxx:3935
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition TTimeStamp.h:45
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
Definition TUUID.h:42
void ReadBuffer(char *&buffer)
Stream UUID from input buffer.
Definition TUUID.cxx:291
void FillBuffer(char *&buffer)
Stream UUID into output buffer.
Definition TUUID.cxx:275
This class represents a WWW compatible URL.
Definition TUrl.h:33
const char * GetAnchor() const
Definition TUrl.h:70
const char * GetUrl(Bool_t withDeflt=kFALSE) const
Return full URL.
Definition TUrl.cxx:390
void SetAnchor(const char *anchor)
Definition TUrl.h:86
const char * GetFileAndOptions() const
Return the file and its options (the string specified behind the ?).
Definition TUrl.cxx:504
const char * GetFile() const
Definition TUrl.h:69
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
Definition TUrl.cxx:660
void SetProtocol(const char *proto, Bool_t setDefaultPort=kFALSE)
Set protocol and, optionally, change the port accordingly.
Definition TUrl.cxx:523
void SetOptions(const char *opt)
Definition TUrl.h:87
const char * GetHostFQDN() const
Return fully qualified domain name of url host.
Definition TUrl.cxx:472
const char * GetOptions() const
Definition TUrl.h:71
void SetHost(const char *host)
Definition TUrl.h:84
const char * GetProtocol() const
Definition TUrl.h:64
void SetFile(const char *file)
Definition TUrl.h:85
Int_t GetPort() const
Definition TUrl.h:78
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.
Definition TUrl.cxx:683
virtual Bool_t SendFileReadProgress(TFile *)
virtual Bool_t SendFileCloseEvent(TFile *)
virtual Bool_t SendFileWriteProgress(TFile *)
Abstract Interface class describing Streamer information for one class.
virtual Int_t GetClassVersion() const =0
const Int_t n
Definition legend1.C:16
TF1 * f1
Definition legend1.C:11
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
R__EXTERN TVirtualRWMutex * gCoreMutex
@ kFileThreadSlot
@ kSTLmap
Definition ESTLType.h:33
@ kSTLmultimap
Definition ESTLType.h:34
ROOT::ESTLType STLKind(std::string_view type)
Converts STL container name to number.
bool IsStdPair(std::string_view name)
Definition TClassEdit.h:184
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
static const char * what
Definition stlLoader.cc:5
Int_t fMode
Definition TSystem.h:125
@ kUndefined
Undefined compression algorithm (must be kept the last of the list in case a new algorithm is added).
@ kUseMin
Compression level reserved when we are not sure what to use (1 is for the fastest compression)
Definition Compression.h:72
TString fFile
Definition TSystem.h:208
Simple struct of the return value of GetStreamerInfoListImpl.
Definition TFile.h:145
TList * fList
Definition TFile.h:146
th1 Draw()
TLine l
Definition textangle.C:4