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