Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TKey.cxx
Go to the documentation of this file.
1// @(#)root/io:$Id$
2// Author: Rene Brun 28/12/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\class TKey
14\ingroup IO
15
16 Book space in a file, create I/O buffers, to fill them, (un)compress them.
17
18 The TKey class includes functions to book space in a file, to create I/O
19 buffers, to fill these buffers, to compress/uncompress data buffers.
20 Before saving (making persistent) an object in a file, a key must
21 be created. The key structure contains all the information to
22 uniquely identify a persistent object in a file.
23 | Data Member | Explanation |
24 |-------------|-------------|
25 | fNbytes | Number of bytes for the compressed object and key. |
26 | fObjlen | Length of uncompressed object. |
27 | fDatime | Date/Time when the object was written. |
28 | fKeylen | Number of bytes for the key structure. |
29 | fCycle | Cycle number of the object. |
30 | fSeekKey | Address of the object on file (points to fNbytes). This is a redundant information used to cross-check the data base integrity. |
31 | fSeekPdir | Pointer to the directory supporting this object.|
32 | fClassName | Object class name. |
33 | fName | Name of the object. |
34 | fTitle | Title of the object. |
35
36 In the 16 highest bits of fSeekPdir is encoded a pid offset. This
37 offset is to be added to the pid index stored in the TRef object
38 and the referenced TObject.
39
40 The TKey class is used by ROOT to:
41 - Write an object in the current directory
42 - Write a new ntuple buffer
43
44 The structure of a file is shown in TFile::TFile.
45 The structure of a directory is shown in TDirectoryFile::TDirectoryFile.
46 The TKey class is used by the TBasket class.
47 See also TTree.
48*/
49
50#include <atomic>
51#include <iostream>
52
53#include "TROOT.h"
54#include "TClass.h"
55#include "TDirectoryFile.h"
56#include "TFile.h"
57#include "TKey.h"
58#include "TBufferFile.h"
59#include "TFree.h"
60#include "TBrowser.h"
61#include "Bytes.h"
62#include "TInterpreter.h"
63#include "TError.h"
65#include "TSchemaRuleSet.h"
66#include "ThreadLocalStorage.h"
67
68#include "RZip.h"
69
70const Int_t kTitleMax = 32000;
71
72#if !defined(_MSC_VER) || (_MSC_VER>1300)
73const ULong64_t kPidOffsetMask = 0xffffffffffffULL;
74#else
75const ULong64_t kPidOffsetMask = 0xffffffffffffUL;
76#endif
78
79const static TString gTDirectoryString("TDirectory");
80std::atomic<UInt_t> keyAbsNumber{0};
81
82
83////////////////////////////////////////////////////////////////////////////////
84/// TKey default constructor.
85
86TKey::TKey() : TNamed(), fDatime((UInt_t)0)
87{
88 Build(0, "", 0);
89
90 fKeylen = Sizeof();
91
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// TKey default constructor.
97
100 Build(motherDir, "", 0);
101
102 fKeylen = Sizeof();
103
104 keyAbsNumber++; SetUniqueID(keyAbsNumber);
105}
106
107////////////////////////////////////////////////////////////////////////////////
108/// Copy a TKey from its original directory to the new 'motherDir'
109
111{
113
114 fPidOffset = orig.fPidOffset + pidOffset;
115 fNbytes = orig.fNbytes;
116 fObjlen = orig.fObjlen;
117 fClassName = orig.fClassName;
118 fName = orig.fName;
119 fTitle = orig.fTitle;
120
121 fCycle = fMotherDir->AppendKey(this);
122 fSeekPdir = 0;
123 fSeekKey = 0;
124 fLeft = 0;
125
129
130 fKeylen = Sizeof(); // fVersion must be set.
131
134 UInt_t alloc = fNbytes + sizeof(Int_t); // The extra Int_t is for any free space information.
135 if (fKeylen < orig.fKeylen) {
136 bufferDecOffset = orig.fKeylen - fKeylen;
138 } else if (fKeylen > orig.fKeylen) {
139 bufferIncOffset = fKeylen - orig.fKeylen;
142 }
143
146
147 // Steal the data from the old key.
148
149 TFile* f = orig.GetFile();
150 if (f) {
151 Int_t nsize = orig.fNbytes;
152 f->Seek(orig.fSeekKey);
153 if( f->ReadBuffer(fBuffer+bufferIncOffset,nsize) )
154 {
155 Error("ReadFile", "Failed to read data.");
156 return;
157 }
158 if (gDebug) {
159 std::cout << "TKey Reading "<<nsize<< " bytes at address "<<fSeekKey<<std::endl;
160 }
161 }
162 fBuffer += bufferDecOffset; // Reset the buffer to be appropriate for this key.
164 Create(nout);
166 Streamer(*fBufferRef); //write key itself again
167}
168
169////////////////////////////////////////////////////////////////////////////////
170/// Create a TKey object to read keys.
171/// Constructor called by TDirectoryFile::ReadKeys and by TFile::TFile.
172/// A TKey object is created to read the keys structure itself.
173
175{
176 Build(motherDir, "", pointer);
177
178 fSeekKey = pointer;
179 fNbytes = nbytes;
180 fBuffer = new char[nbytes];
182}
183
184////////////////////////////////////////////////////////////////////////////////
185/// Create a TKey object with the specified name, title for the given class.
186///
187/// WARNING: in name avoid special characters like '^','$','.' that are used
188/// by the regular expression parser (see TRegexp).
189
190TKey::TKey(const char *name, const char *title, const TClass *cl, Int_t nbytes, TDirectory* motherDir)
191 : TNamed(name,title)
192{
193 Build(motherDir, cl->GetName(), -1);
194
195 fKeylen = Sizeof();
196 fObjlen = nbytes;
197 Create(nbytes);
198}
199
200////////////////////////////////////////////////////////////////////////////////
201/// Create a TKey object with the specified name, title for the given class.
202///
203/// WARNING: in name avoid special characters like '^','$','.' that are used
204/// by the regular expression parser (see TRegexp).
205
207 : TNamed(name,title)
208{
209 Build(motherDir, cl->GetName(), -1);
210
211 fKeylen = Sizeof();
212 fObjlen = nbytes;
213 Create(nbytes);
214}
215
216////////////////////////////////////////////////////////////////////////////////
217/// Create a TKey object for a TObject* and fill output buffer
218///
219/// WARNING: in name avoid special characters like '^','$','.' that are used
220/// by the regular expression parser (see TRegexp).
221
223 : TNamed(name, obj->GetTitle())
224{
225 R__ASSERT(obj);
226
227 if (!obj->IsA()->HasDefaultConstructor()) {
228 Warning("TKey", "since %s has no public constructor\n"
229 "\twhich can be called without argument, objects of this class\n"
230 "\tcan not be read with the current library. You will need to\n"
231 "\tadd a default constructor before attempting to read it.",
232 obj->ClassName());
233 }
234
235 Build(motherDir, obj->ClassName(), -1);
236
237 Int_t lbuf, nout, noutot, bufmax, nzip;
240 fCycle = fMotherDir->AppendKey(this);
241
242 Streamer(*fBufferRef); //write key itself
244 fBufferRef->MapObject(obj); //register obj in map in case of self reference
245 ((TObject*)obj)->Streamer(*fBufferRef); //write object
247 fObjlen = lbuf - fKeylen;
248
251 if (cxlevel > 0 && fObjlen > 256) {
252 Int_t nbuffers = 1 + (fObjlen - 1)/kMAXZIPBUF;
253 Int_t buflen = std::max(512,fKeylen + fObjlen + 9*nbuffers + 28); //add 28 bytes in case object is placed in a deleted gap
254 fBuffer = new char[buflen];
255 char *objbuf = fBufferRef->Buffer() + fKeylen;
256 char *bufcur = &fBuffer[fKeylen];
257 noutot = 0;
258 nzip = 0;
259 for (Int_t i = 0; i < nbuffers; ++i) {
260 if (i == nbuffers - 1) bufmax = fObjlen - nzip;
261 else bufmax = kMAXZIPBUF;
263 if (nout == 0 || nout >= fObjlen) { //this happens when the buffer cannot be compressed
264 delete[] fBuffer;
265 bufcur = nullptr;
269 Streamer(*fBufferRef); //write key itself again
270 return;
271 }
272 bufcur += nout;
273 noutot += nout;
275 nzip += kMAXZIPBUF;
276 }
277 Create(noutot);
279 Streamer(*fBufferRef); //write key itself again
281 delete fBufferRef; fBufferRef = 0;
282 } else {
286 Streamer(*fBufferRef); //write key itself again
287 }
288}
289
290////////////////////////////////////////////////////////////////////////////////
291/// Create a TKey object for any object obj of class cl d and fill
292/// output buffer.
293///
294/// WARNING: in name avoid special characters like '^','$','.' that are used
295/// by the regular expression parser (see TRegexp).
296
297TKey::TKey(const void *obj, const TClass *cl, const char *name, Int_t bufsize, TDirectory *motherDir) : TNamed(name, "")
298{
299 R__ASSERT(obj && cl);
300
301 if (!cl->HasDefaultConstructor()) {
302 Warning("TKey", "since %s has no public constructor\n"
303 "\twhich can be called without argument, objects of this class\n"
304 "\tcan not be read with the current library. You will need to\n"
305 "\tadd a default constructor before attempting to read it.",
306 cl->GetName());
307 }
308
309 TClass *clActual = cl->GetActualClass(obj);
310 const void* actualStart;
311 if (clActual) {
312 const char *temp = (const char*) obj;
313 // clActual->GetStreamerInfo();
314 Int_t offset = (cl != clActual) ?
315 clActual->GetBaseClassOffset(cl) : 0;
316 temp -= offset;
317 actualStart = temp;
318 } else {
319 // We could not determine the real type of this object,
320 // let's assume it is the one given by the caller.
321 clActual = const_cast<TClass*>(cl);
322 actualStart = obj;
323 }
324
325 Build(motherDir, clActual->GetName(), -1);
326
329
330 Streamer(*fBufferRef); //write key itself
332
333 Int_t lbuf, nout, noutot, bufmax, nzip;
334
335 fBufferRef->MapObject(actualStart,clActual); //register obj in map in case of self reference
336 clActual->Streamer((void*)actualStart, *fBufferRef); //write object
338 fObjlen = lbuf - fKeylen;
339
340 // Append to mother directory only after the call to Streamer() was
341 // successful (and didn't throw).
342 fCycle = fMotherDir->AppendKey(this);
343
346 if (cxlevel > 0 && fObjlen > 256) {
347 Int_t nbuffers = 1 + (fObjlen - 1)/kMAXZIPBUF;
348 Int_t buflen = std::max(512,fKeylen + fObjlen + 9*nbuffers + 28); //add 28 bytes in case object is placed in a deleted gap
349 fBuffer = new char[buflen];
350 char *objbuf = fBufferRef->Buffer() + fKeylen;
351 char *bufcur = &fBuffer[fKeylen];
352 noutot = 0;
353 nzip = 0;
354 for (Int_t i = 0; i < nbuffers; ++i) {
355 if (i == nbuffers - 1) bufmax = fObjlen - nzip;
356 else bufmax = kMAXZIPBUF;
358 if (nout == 0 || nout >= fObjlen) { //this happens when the buffer cannot be compressed
359 delete[] fBuffer;
360 bufcur = nullptr;
364 Streamer(*fBufferRef); //write key itself again
365 return;
366 }
367 bufcur += nout;
368 noutot += nout;
370 nzip += kMAXZIPBUF;
371 }
372 Create(noutot);
374 Streamer(*fBufferRef); //write key itself again
376 delete fBufferRef; fBufferRef = 0;
377 } else {
381 Streamer(*fBufferRef); //write key itself again
382 }
383}
384
385/// Core of uncompressing the key payload. Returns number of bytes uncompressed.
386/// We expect that the compressedBuffer contains the entire key (key header + payload).
387/// The target buffer must have space for at least fObjLen bytes.
388/// Lastly, the object length must be larger than the key payload, i.e. we already know that
389/// we have a compressed payload.
391{
392 auto objbuf = reinterpret_cast<unsigned char *>(targetBuffer) + fKeylen;
393 auto bufcur = reinterpret_cast<const unsigned char *>(&compressedBuffer[fKeylen]);
394 Int_t nin, nout = 0, nbuf;
395 Int_t noutot = 0;
398 while (nbytesRemain >= ROOT::Internal::kZipHeaderSize) {
400 if ((hc != 0) || (nin > nbytesRemain) || (nbuf > objlenRemain))
401 return 0;
403 if (!nout)
404 return 0;
405 noutot += nout;
406 if (noutot >= fObjlen)
407 break;
408 bufcur += nin;
409 objbuf += nout;
410 nbytesRemain -= nin;
412 }
413 return nout;
414}
415
416////////////////////////////////////////////////////////////////////////////////
417/// Method used in all TKey constructor to initialize basic data fields.
418///
419/// The member filepos is used to calculate correct version number of key
420/// if filepos==-1, end of file position is used.
421
422void TKey::Build(TDirectory* motherDir, const char* classname, Long64_t filepos)
423{
425
426 fPidOffset = 0;
427 fNbytes = 0;
428 fBuffer = 0;
429 fKeylen = 0;
430 fObjlen = 0;
431 fBufferRef = 0;
432 fCycle = 0;
433 fSeekPdir = 0;
434 fSeekKey = 0;
435 fLeft = 0;
436
437 fClassName = classname;
438 //the following test required for forward and backward compatibility
439 if (fClassName == "TDirectoryFile") SetBit(kIsDirectoryFile);
440
442
443 if ((filepos==-1) && GetFile()) filepos = GetFile()->GetEND();
445
447
450}
451
452////////////////////////////////////////////////////////////////////////////////
453/// Read object from disk and call its Browse() method.
454///
455/// If object with same name already exist in memory delete it (like
456/// TDirectoryFile::Get() is doing), except when the key references a
457/// folder in which case we don't want to re-read the folder object
458/// since it might contain new objects not yet saved.
459
461{
462 if (fMotherDir==0) return;
463
465
466 void* obj = fMotherDir->GetList()->FindObject(GetName());
467 if (obj && objcl->IsTObject()) {
468 TObject *tobj = (TObject*) objcl->DynamicCast(TObject::Class(), obj);
469 if (!tobj->IsFolder()) {
470 if (tobj->InheritsFrom(TCollection::Class()))
471 tobj->Delete(); // delete also collection elements
472 delete tobj;
473 obj = 0;
474 }
475 }
476
477 if (!obj)
478 obj = ReadObj();
479
480 if (b && obj) {
481 objcl->Browse(obj,b);
482 b->SetRefreshFlag(kTRUE);
483 }
484}
485
486////////////////////////////////////////////////////////////////////////////////
487/// Create a TKey object of specified size.
488///
489/// If externFile!=0, key will be allocated in specified file, otherwise file
490/// of mother directory will be used.
491
493{
495
496 TFile *f = externFile;
497 if (!f) f = GetFile();
498 if (!f) {
499 Error("Create","Cannot create key without file");
500 return;
501 }
502
504 TList *lfree = f->GetListOfFree();
505 TFree *f1 = (TFree*)lfree->First();
506//*-*-------------------find free segment
507//*-* =================
508 TFree *bestfree = f1->GetBestFree(lfree,nsize);
509 if (bestfree == 0) {
510 Error("Create","Cannot allocate %d bytes for ID = %s Title = %s",
512 return;
513 }
514
515 if (f->TestBit(TFile::kReproducible))
517
518 fDatime.Set();
519 fSeekKey = bestfree->GetFirst();
520//*-*----------------- Case Add at the end of the file
521 if (fSeekKey >= f->GetEND()) {
522 f->SetEND(fSeekKey+nsize);
523 bestfree->SetFirst(fSeekKey+nsize);
524 if (f->GetEND() > bestfree->GetLast()) {
525 bestfree->SetLast(bestfree->GetLast() + 1000000000);
526 }
527 fLeft = -1;
528 if (!fBuffer) fBuffer = new char[nsize];
529 } else {
530 fLeft = Int_t(bestfree->GetLast() - fSeekKey - nsize + 1);
531 }
532//*-*----------------- Case where new object fills exactly a deleted gap
533 fNbytes = nsize;
534 if (fLeft == 0) {
535 if (!fBuffer) {
536 fBuffer = new char[nsize];
537 }
538 lfree->Remove(bestfree);
539 delete bestfree;
540 }
541//*-*----------------- Case where new object is placed in a deleted gap larger than itself
542 if (fLeft > 0) { // found a bigger segment
543 if (!fBuffer) {
544 fBuffer = new char[nsize+sizeof(Int_t)];
545 }
546 char *buffer = fBuffer+nsize;
547 Int_t nbytesleft = -fLeft; // set header of remaining record
548 tobuf(buffer, nbytesleft);
549 bestfree->SetFirst(fSeekKey+nsize);
550 }
551
552 fSeekPdir = externFile ? externFile->GetSeekDir() : fMotherDir->GetSeekDir();
553}
554
555////////////////////////////////////////////////////////////////////////////////
556/// TKey default destructor.
557
559{
561 fMotherDir->GetListOfKeys()->Remove(this);
563}
564
565////////////////////////////////////////////////////////////////////////////////
566/// Delete an object from the file.
567///
568/// Note: the key is not deleted. You still have to call "delete key".
569/// This is different from the behaviour of TObject::Delete()!
570
572{
574 // TDirectoryFile assumes that its location on file never change (for example updates are partial)
575 // and never checks if the space might have been released and thus over-write any data that might
576 // have been written there.
577 if (option && option[0] == 'v')
578 printf("Rejected attempt to delete TDirectoryFile key: %s at address %lld, nbytes = %d\n",
580 return;
581 }
582 if (option && option[0] == 'v') printf("Deleting key: %s at address %lld, nbytes = %d\n",GetName(),fSeekKey,fNbytes);
583 Long64_t first = fSeekKey;
584 Long64_t last = fSeekKey + fNbytes -1;
585 if (GetFile()) GetFile()->MakeFree(first, last); // release space used by this key
586 fMotherDir->GetListOfKeys()->Remove(this);
587}
588
589////////////////////////////////////////////////////////////////////////////////
590/// Delete key buffer(s).
591
593{
594 if (fBufferRef) {
595 delete fBufferRef;
596 fBufferRef = 0;
597 } else {
598 // We only need to delete fBuffer if fBufferRef is zero because
599 // if fBufferRef exists, we delegate ownership of fBuffer to fBufferRef.
600 if (fBuffer) {
601 delete [] fBuffer;
602 }
603 }
604 fBuffer = 0;
605}
606
607////////////////////////////////////////////////////////////////////////////////
608/// Return cycle number associated to this key.
609
611{
612 return ((fCycle >0) ? fCycle : -fCycle);
613}
614
615////////////////////////////////////////////////////////////////////////////////
616/// Returns file to which key belong.
617
619{
620 return fMotherDir!=0 ? fMotherDir->GetFile() : gFile;
621}
622
623////////////////////////////////////////////////////////////////////////////////
624/// Returns the "KEEP" status.
625
627{
628 return ((fCycle >0) ? 0 : 1);
629}
630
631////////////////////////////////////////////////////////////////////////////////
632/// Encode key header into output buffer.
633
634void TKey::FillBuffer(char *&buffer)
635{
636 tobuf(buffer, fNbytes);
638 tobuf(buffer, version);
639
640 tobuf(buffer, fObjlen);
642 TDatime((UInt_t) 1).FillBuffer(buffer);
643 else
644 fDatime.FillBuffer(buffer);
645 tobuf(buffer, fKeylen);
646 tobuf(buffer, fCycle);
647 if (fVersion > 1000) {
648 tobuf(buffer, fSeekKey);
649
650 // We currently store in the 16 highest bit of fSeekPdir the value of
651 // fPidOffset. This offset is used when a key (or basket) is transferred from one
652 // file to the other. In this case the TRef and TObject might have stored a
653 // pid index (to retrieve TProcessIDs) which refered to their order on the original
654 // file, the fPidOffset is to be added to those values to correctly find the
655 // TProcessID. This fPidOffset needs to be increment if the key/basket is copied
656 // and need to be zero for new key/basket.
658 tobuf(buffer, pdir);
659 } else {
660 tobuf(buffer, (Int_t)fSeekKey);
661 tobuf(buffer, (Int_t)fSeekPdir);
662 }
664 // We want to record "TDirectory" instead of TDirectoryFile so that the file can be read by ancient version of ROOT.
665 gTDirectoryString.FillBuffer(buffer);
666 } else {
667 fClassName.FillBuffer(buffer);
668 }
669 fName.FillBuffer(buffer);
670 fTitle.FillBuffer(buffer);
671}
672
673////////////////////////////////////////////////////////////////////////////////
674/// Increment fPidOffset by 'offset'.
675///
676/// This offset is used when a key (or basket) is transferred from one file to
677/// the other. In this case the TRef and TObject might have stored a pid
678/// index (to retrieve TProcessIDs) which refered to their order on the
679/// original file, the fPidOffset is to be added to those values to correctly
680/// find the TProcessID. This fPidOffset needs to be increment if the
681/// key/basket is copied and need to be zero for new key/basket.
682
684{
686 if (fPidOffset) {
687 // We currently store fPidOffset in the 16 highest bit of fSeekPdir, which
688 // need to be store as a 64 bit integer. So we require this key to be
689 // a 'large file' key.
690 if (fVersion<1000) fVersion += 1000;
691 }
692}
693
694////////////////////////////////////////////////////////////////////////////////
695/// Check if object referenced by the key is a folder.
696
698{
699 Bool_t ret = kFALSE;
700
701 TClass *classPtr = TClass::GetClass((const char *) fClassName);
702 if (classPtr && classPtr->GetState() > TClass::kEmulated && classPtr->IsTObject()) {
703 TObject *obj = (TObject *) classPtr->DynamicCast(TObject::Class(), classPtr->New(TClass::kDummyNew));
704 if (obj) {
705 ret = obj->IsFolder();
706 delete obj;
707 }
708 }
709
710 return ret;
711}
712
713////////////////////////////////////////////////////////////////////////////////
714/// Set the "KEEP" status.
715///
716/// When the KEEP flag is set to 1 the object cannot be purged.
717
719{
720 if (fCycle >0) fCycle = -fCycle;
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// List Key contents.
725/// Add indicator of whether it is the current item or a backup copy.
726
727void TKey::ls(Bool_t current) const
728{
730 std::cout <<"KEY: "<<fClassName<<"\t"<<GetName()<<";"<<GetCycle()<<"\t"<<GetTitle();
731 std::cout << (current ? " [current cycle]" : " [backup cycle]");
732 std::cout <<std::endl;
733}
734
735////////////////////////////////////////////////////////////////////////////////
736/// List Key contents.
737
738void TKey::ls(Option_t *) const
739{
741 std::cout <<"KEY: "<<fClassName<<"\t"<<GetName()<<";"<<GetCycle()<<"\t"<<GetTitle()<<std::endl;
742}
743
744////////////////////////////////////////////////////////////////////////////////
745/// Print key contents.
746
748{
749 printf("TKey Name = %s, Title = %s, Cycle = %d\n",GetName(),GetTitle(),GetCycle());
750}
751
752////////////////////////////////////////////////////////////////////////////////
753/// To read a TObject* from the file.
754///
755/// The object associated to this key is read from the file into memory
756/// Once the key structure is read (via Streamer) the class identifier
757/// of the object is known.
758/// Using the class identifier we find the TClass object for this class.
759/// A TClass object contains a full description (i.e. dictionary) of the
760/// associated class. In particular the TClass object can create a new
761/// object of the class type it describes. This new object now calls its
762/// Streamer function to rebuilt itself.
763///
764/// Use TKey::ReadObjectAny to read any object non-derived from TObject
765///
766/// ### Note
767/// A C style cast can only be used in the case where the final class
768/// of this object derives from TObject as a first inheritance, otherwise
769/// one must use a dynamic_cast.
770///
771/// #### Example1: simplified case
772/// ~~~{.cpp}
773/// class MyClass : public TObject, public AnotherClass
774/// ~~~
775/// then on return, one get away with using:
776/// ~~~{.cpp}
777/// MyClass *obj = (MyClass*)key->ReadObj();
778/// ~~~
779///
780/// #### Example2: Usual case (recommended unless performance is critical)
781/// ~~~{.cpp}
782/// MyClass *obj = dynamic_cast<MyClass*>(key->ReadObj());
783/// ~~~
784/// which support also the more complex inheritance like:
785/// ~~~{.cpp}
786/// class MyClass : public AnotherClass, public TObject
787/// ~~~
788///
789/// Of course, `dynamic_cast<>` can also be used in the example 1.
790
792{
794 if (!cl) {
795 Error("ReadObj", "Unknown class %s", fClassName.Data());
796 return 0;
797 }
798 if (!cl->IsTObject()) {
799 // in principle user should call TKey::ReadObjectAny!
800 return (TObject*)ReadObjectAny(0);
801 }
802
804 if (!bufferRef.Buffer()) {
805 Error("ReadObj", "Cannot allocate buffer: fObjlen = %d", fObjlen);
806 return 0;
807 }
808 if (GetFile()==0) return 0;
809 bufferRef.SetParent(GetFile());
810 bufferRef.SetPidOffset(fPidOffset);
811
812 std::unique_ptr<char []> compressedBuffer;
813 auto storeBuffer = fBuffer;
814 if (fObjlen > fNbytes-fKeylen) {
815 compressedBuffer.reset(new char[fNbytes]);
817 if( !ReadFile() ) //Read object structure from file
818 {
819 fBuffer = 0;
820 return 0;
821 }
823 } else {
824 fBuffer = bufferRef.Buffer();
825 if( !ReadFile() ) { //Read object structure from file
826
827 fBuffer = 0;
828 return 0;
829 }
830 }
832
833 // get version of key
834 bufferRef.SetBufferOffset(sizeof(fNbytes));
835 Version_t kvers = bufferRef.ReadVersion();
836
837 bufferRef.SetBufferOffset(fKeylen);
838 TObject *tobj = 0;
839 // Create an instance of this class
840
841 char *pobj = (char*)cl->New();
842 if (!pobj) {
843 Error("ReadObj", "Cannot create new object of class %s", fClassName.Data());
844 return 0;
845 }
847 if (baseOffset==-1) {
848 // cl does not inherit from TObject.
849 // Since this is not possible yet, the only reason we could reach this code
850 // is because something is screw up in the ROOT code.
851 Fatal("ReadObj","Incorrect detection of the inheritance from TObject for class %s.\n",
852 fClassName.Data());
853 }
855 if (kvers > 1)
856 bufferRef.MapObject(pobj,cl); //register obj in map to handle self reference
857
858 if (fObjlen > fNbytes-fKeylen) {
860 compressedBuffer.reset(nullptr);
861 if (nout) {
862 tobj->Streamer(bufferRef); //does not work with example 2 above
863 } else {
864 // Even-though we have a TObject, if the class is emulated the virtual
865 // table may not be 'right', so let's go via the TClass.
866 cl->Destructor(pobj);
867 return nullptr;
868 }
869 } else {
870 tobj->Streamer(bufferRef);
871 }
872
873 if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
874
876 TDirectory *dir = static_cast<TDirectoryFile*>(tobj);
877 dir->SetName(GetName());
878 dir->SetTitle(GetTitle());
879 dir->SetMother(fMotherDir);
880 fMotherDir->Append(dir);
881 }
882
883 // Append the object to the directory if requested:
884 {
886 if (addfunc) {
887 addfunc(pobj, fMotherDir);
888 }
889 }
890
891 return tobj;
892}
893
894////////////////////////////////////////////////////////////////////////////////
895/// To read a TObject* from bufferRead.
896///
897/// This function is identical to TKey::ReadObj, but it reads directly from
898/// bufferRead instead of reading from a file.
899/// The object associated to this key is read from the buffer into memory
900/// Using the class identifier we find the TClass object for this class.
901/// A TClass object contains a full description (i.e. dictionary) of the
902/// associated class. In particular the TClass object can create a new
903/// object of the class type it describes. This new object now calls its
904/// Streamer function to rebuilt itself.
905///
906/// ### Note
907/// This function is called only internally by ROOT classes.
908/// Although being public it is not supposed to be used outside ROOT.
909/// If used, you must make sure that the bufferRead is large enough to
910/// accommodate the object being read.
911
913{
914
916 if (!cl) {
917 Error("ReadObjWithBuffer", "Unknown class %s", fClassName.Data());
918 return 0;
919 }
920 if (!cl->IsTObject()) {
921 // in principle user should call TKey::ReadObjectAny!
922 return (TObject*)ReadObjectAny(0);
923 }
924
926 if (!bufferRef.Buffer()) {
927 Error("ReadObjWithBuffer", "Cannot allocate buffer: fObjlen = %d", fObjlen);
928 return 0;
929 }
930 if (GetFile()==0) return 0;
931 bufferRef.SetParent(GetFile());
932 bufferRef.SetPidOffset(fPidOffset);
933
934 auto storeBuffer = fBuffer;
935 if (fObjlen > fNbytes-fKeylen) {
938 } else {
939 fBuffer = bufferRef.Buffer();
940 ReadFile(); //Read object structure from file
941 }
943
944 // get version of key
945 bufferRef.SetBufferOffset(sizeof(fNbytes));
946 Version_t kvers = bufferRef.ReadVersion();
947
948 bufferRef.SetBufferOffset(fKeylen);
949 TObject *tobj = 0;
950 // Create an instance of this class
951
952 char *pobj = (char*)cl->New();
953 if (!pobj) {
954 Error("ReadObjWithBuffer", "Cannot create new object of class %s", fClassName.Data());
955 return 0;
956 }
958 if (baseOffset==-1) {
959 // cl does not inherit from TObject.
960 // Since this is not possible yet, the only reason we could reach this code
961 // is because something is screw up in the ROOT code.
962 Fatal("ReadObjWithBuffer","Incorrect detection of the inheritance from TObject for class %s.\n",
963 fClassName.Data());
964 }
966
967 if (kvers > 1)
968 bufferRef.MapObject(pobj,cl); //register obj in map to handle self reference
969
970 if (fObjlen > fNbytes-fKeylen) {
972 if (nout) {
973 tobj->Streamer(bufferRef); //does not work with example 2 above
974 } else {
975 // Even-though we have a TObject, if the class is emulated the virtual
976 // table may not be 'right', so let's go via the TClass.
977 cl->Destructor(pobj);
978 return nullptr;
979 }
980 } else {
981 tobj->Streamer(bufferRef);
982 }
983
984 if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
985
987 TDirectory *dir = static_cast<TDirectoryFile*>(tobj);
988 dir->SetName(GetName());
989 dir->SetTitle(GetTitle());
990 dir->SetMother(fMotherDir);
991 fMotherDir->Append(dir);
992 }
993
994 // Append the object to the directory if requested:
995 {
997 if (addfunc) {
998 addfunc(pobj, fMotherDir);
999 }
1000 }
1001
1002 return tobj;
1003}
1004
1005////////////////////////////////////////////////////////////////////////////////
1006/// To read an object (non deriving from TObject) from the file.
1007///
1008/// If expectedClass is not null, we checked that that actual class of the
1009/// object stored is suitable to be stored in a pointer pointing to an object
1010/// of class 'expectedClass'. We also adjust the value of the returned address
1011/// so that it is suitable to be cast (C-Style)
1012/// a pointer pointing to an object of class 'expectedClass'.
1013///
1014/// So for example if the class Bottom inherits from Top and the object
1015/// stored is of type Bottom you can safely do:
1016/// ~~~{.cpp}
1017/// auto TopClass = TClass::GetClass("Top");
1018/// auto ptr = (Top*) key->ReadObjectAny( TopClass );
1019/// if (ptr==0) printError("the object stored in the key is not of the expected type\n");
1020/// ~~~
1021/// The object associated to this key is read from the file into memory.
1022/// Once the key structure is read (via Streamer) the class identifier
1023/// of the object is known.
1024/// Using the class identifier we find the TClass object for this class.
1025/// A TClass object contains a full description (i.e. dictionary) of the
1026/// associated class. In particular the TClass object can create a new
1027/// object of the class type it describes. This new object now calls its
1028/// Streamer function to rebuilt itself.
1029
1031{
1033 if (!bufferRef.Buffer()) {
1034 Error("ReadObj", "Cannot allocate buffer: fObjlen = %d", fObjlen);
1035 return 0;
1036 }
1037 if (GetFile()==0) return 0;
1038 bufferRef.SetParent(GetFile());
1039 bufferRef.SetPidOffset(fPidOffset);
1040
1041 std::unique_ptr<char []> compressedBuffer;
1042 auto storeBuffer = fBuffer;
1043 if (fObjlen > fNbytes-fKeylen) {
1044 compressedBuffer.reset(new char[fNbytes]);
1045 fBuffer = compressedBuffer.get();
1046 ReadFile(); //Read object structure from file
1047 memcpy(bufferRef.Buffer(),fBuffer,fKeylen);
1048 } else {
1049 fBuffer = bufferRef.Buffer();
1050 ReadFile(); //Read object structure from file
1051 }
1053
1054 // get version of key
1055 bufferRef.SetBufferOffset(sizeof(fNbytes));
1056 Version_t kvers = bufferRef.ReadVersion();
1057
1058 bufferRef.SetBufferOffset(fKeylen);
1060 TClass *clOnfile = 0;
1061 if (!cl) {
1062 Error("ReadObjectAny", "Unknown class %s", fClassName.Data());
1063 return 0;
1064 }
1065 Int_t baseOffset = 0;
1066 if (expectedClass) {
1067 // baseOffset will be -1 if cl does not inherit from expectedClass
1069 if (baseOffset == -1) {
1070 // The 2 classes are unrelated, maybe there is a converter between the 2.
1071
1072 if (!expectedClass->GetSchemaRules() ||
1073 !expectedClass->GetSchemaRules()->HasRuleWithSourceClass(cl->GetName()))
1074 {
1075 // There is no converter
1076 return 0;
1077 }
1078 baseOffset = 0; // For now we do not support requesting from a class that is the base of one of the class for which there is transformation to ....
1079 clOnfile = cl;
1080 cl = const_cast<TClass*>(expectedClass);
1081 if (gDebug > 0)
1082 Info("ReadObjectAny", "Using Converter StreamerInfo from %s to %s", clOnfile->GetName(),
1083 expectedClass->GetName());
1084 }
1085 if (cl->GetState() > TClass::kEmulated && expectedClass->GetState() <= TClass::kEmulated) {
1086 //we cannot mix a compiled class with an emulated class in the inheritance
1087 Warning("ReadObjectAny",
1088 "Trying to read an emulated class (%s) to store in a compiled pointer (%s)",
1089 cl->GetName(),expectedClass->GetName());
1090 }
1091 }
1092 // Create an instance of this class
1093
1094 void *pobj = cl->New();
1095 if (!pobj) {
1096 Error("ReadObjectAny", "Cannot create new object of class %s", fClassName.Data());
1097 return 0;
1098 }
1099
1100 if (kvers > 1)
1101 bufferRef.MapObject(pobj,cl); //register obj in map to handle self reference
1102
1103 if (fObjlen > fNbytes-fKeylen) {
1104 Int_t nout = UnzipBuffer(bufferRef.Buffer(), compressedBuffer.get());
1105 if (nout) {
1106 cl->Streamer((void*)pobj, bufferRef, clOnfile); //read object
1107 } else {
1108 cl->Destructor(pobj);
1109 return nullptr;
1110 }
1111 } else {
1112 cl->Streamer((void*)pobj, bufferRef, clOnfile); //read object
1113 }
1114
1115 if (cl->IsTObject()) {
1117 if (tobjBaseOffset == -1) {
1118 Fatal("ReadObj","Incorrect detection of the inheritance from TObject for class %s.\n",
1119 fClassName.Data());
1120 }
1121 TObject *tobj = (TObject*)( ((char*)pobj) + tobjBaseOffset);
1122
1123 // See similar adjustments in ReadObj
1124 if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
1125
1127 TDirectory *dir = static_cast<TDirectoryFile*>(tobj);
1128 dir->SetName(GetName());
1129 dir->SetTitle(GetTitle());
1130 dir->SetMother(fMotherDir);
1131 fMotherDir->Append(dir);
1132 }
1133 }
1134
1135 {
1136 // Append the object to the directory if requested:
1138 if (addfunc) {
1139 addfunc(pobj, fMotherDir);
1140 }
1141 }
1142
1143 return ( ((char*)pobj) + baseOffset );
1144}
1145
1146////////////////////////////////////////////////////////////////////////////////
1147/// To read an object from the file.
1148///
1149/// The object associated to this key is read from the file into memory.
1150/// Before invoking this function, obj has been created via the
1151/// default constructor.
1152
1154{
1155 if (!obj || (GetFile()==0)) return 0;
1156
1158 bufferRef.SetParent(GetFile());
1159 bufferRef.SetPidOffset(fPidOffset);
1160
1161 if (fVersion > 1)
1162 bufferRef.MapObject(obj); //register obj in map to handle self reference
1163
1164 std::unique_ptr<char []> compressedBuffer;
1165 auto storeBuffer = fBuffer;
1166 if (fObjlen > fNbytes-fKeylen) {
1167 compressedBuffer.reset(new char[fNbytes]);
1168 fBuffer = compressedBuffer.get();
1169 ReadFile(); //Read object structure from file
1170 memcpy(bufferRef.Buffer(),fBuffer,fKeylen);
1171 } else {
1172 fBuffer = bufferRef.Buffer();
1173 ReadFile(); //Read object structure from file
1174 }
1176
1177 bufferRef.SetBufferOffset(fKeylen);
1178 if (fObjlen > fNbytes-fKeylen) {
1179 Int_t nout = UnzipBuffer(bufferRef.Buffer(), compressedBuffer.get());
1180 if (nout)
1181 obj->Streamer(bufferRef);
1182 } else {
1183 obj->Streamer(bufferRef);
1184 }
1185
1186 // Append the object to the directory if requested:
1187 {
1188 ROOT::DirAutoAdd_t addfunc = obj->IsA()->GetDirectoryAutoAdd();
1189 if (addfunc) {
1190 addfunc(obj, fMotherDir);
1191 }
1192 }
1193
1194 return fNbytes;
1195}
1196
1197////////////////////////////////////////////////////////////////////////////////
1198/// Decode input buffer.
1199///
1200/// In some situation will add key to gDirectory.
1201
1202void TKey::ReadBuffer(char *&buffer)
1203{
1204 ReadKeyBuffer(buffer);
1205
1206 if (!gROOT->ReadingObject() && gDirectory) {
1207 if (fSeekPdir != gDirectory->GetSeekDir()) gDirectory->AppendKey(this);
1208 }
1209}
1210
1211////////////////////////////////////////////////////////////////////////////////
1212/// Decode input buffer.
1213
1214void TKey::ReadKeyBuffer(char *&buffer)
1215{
1216 frombuf(buffer, &fNbytes);
1218 frombuf(buffer,&version);
1220 frombuf(buffer, &fObjlen);
1221 fDatime.ReadBuffer(buffer);
1222 frombuf(buffer, &fKeylen);
1223 frombuf(buffer, &fCycle);
1224 if (fVersion > 1000) {
1225 frombuf(buffer, &fSeekKey);
1226
1227 // We currently store in the 16 highest bit of fSeekPdir the value of
1228 // fPidOffset. This offset is used when a key (or basket) is transferred from one
1229 // file to the other. In this case the TRef and TObject might have stored a
1230 // pid index (to retrieve TProcessIDs) which refered to their order on the original
1231 // file, the fPidOffset is to be added to those values to correctly find the
1232 // TProcessID. This fPidOffset needs to be increment if the key/basket is copied
1233 // and need to be zero for new key/basket.
1234 Long64_t pdir;
1235 frombuf(buffer, &pdir);
1238 } else {
1240 frombuf(buffer, &seekkey); fSeekKey = (Long64_t)seekkey;
1242 }
1243 fClassName.ReadBuffer(buffer);
1244 //the following test required for forward and backward compatibility
1245 if (fClassName == "TDirectory") {
1246 fClassName = "TDirectoryFile";
1248 }
1249
1250 fName.ReadBuffer(buffer);
1251 fTitle.ReadBuffer(buffer);
1252}
1253
1254////////////////////////////////////////////////////////////////////////////////
1255/// Read the key structure from the file
1256
1258{
1259 TFile* f = GetFile();
1260 if (f==0) return kFALSE;
1261
1263 f->Seek(fSeekKey);
1264 if( f->ReadBuffer(fBuffer,nsize) )
1265 {
1266 Error("ReadFile", "Failed to read data.");
1267 return kFALSE;
1268 }
1269 if (gDebug) {
1270 std::cout << "TKey Reading "<<nsize<< " bytes at address "<<fSeekKey<<std::endl;
1271 }
1272 return kTRUE;
1273}
1274
1275////////////////////////////////////////////////////////////////////////////////
1276/// Set parent in key buffer.
1277
1278void TKey::SetParent(const TObject *parent)
1279{
1280 if (fBufferRef) fBufferRef->SetParent((TObject*)parent);
1281}
1282
1283////////////////////////////////////////////////////////////////////////////////
1284/// Reset the key as it had not been 'filled' yet.
1285
1287{
1288 fPidOffset = 0;
1289 fNbytes = 0;
1290 fBuffer = 0;
1291 fObjlen = 0;
1292 fCycle = 0;
1293 fSeekPdir = 0;
1294 fSeekKey = 0;
1295 fLeft = 0;
1296 fDatime = (UInt_t)0;
1297
1298 // fBufferRef and fKeylen intentionally not reset/changed
1299
1301}
1302
1303////////////////////////////////////////////////////////////////////////////////
1304/// Return the size in bytes of the key header structure.
1305///
1306/// An explanation about the nbytes (Int_t nbytes) variable used in the
1307/// function. The size of fSeekKey and fSeekPdir is 8 instead of 4 if version is
1308/// greater than 1000.
1309/// | Component | Sizeof |
1310/// |-------------------|------------|
1311/// | fNbytes | 4 |
1312/// | sizeof(Version_t) | 2 |
1313/// | fObjlen | 4 |
1314/// | fDatime | 4 |
1315/// | fKeylen | 2 |
1316/// | fCycle | 2 |
1317/// | fSeekKey | 4 or 8 |
1318/// | fSeekPdir | 4 or 8 |
1319/// | **FIXED TOTAL** | 26 or 34 |
1320/// | fClassName | 1+ bytes |
1321/// | fName | 1+ bytes |
1322/// | fTitle | 1+ bytes |
1323/// | **TOTAL** | 29+ or 37+ |
1324
1326{
1327 Int_t nbytes = 22; if (fVersion > 1000) nbytes += 8;
1328 nbytes += fDatime.Sizeof();
1330 nbytes += 11; // strlen("TDirectory")+1
1331 } else {
1333 }
1334 nbytes += fName.Sizeof();
1335 nbytes += fTitle.Sizeof();
1336 return nbytes;
1337}
1338
1339////////////////////////////////////////////////////////////////////////////////
1340/// Stream a class object.
1341
1343{
1345 if (b.IsReading()) {
1346 b >> fNbytes;
1348 b >> fObjlen;
1350 b >> fKeylen;
1351 b >> fCycle;
1352 if (fVersion > 1000) {
1353 b >> fSeekKey;
1354
1355 // We currently store in the 16 highest bit of fSeekPdir the value of
1356 // fPidOffset. This offset is used when a key (or basket) is transferred from one
1357 // file to the other. In this case the TRef and TObject might have stored a
1358 // pid index (to retrieve TProcessIDs) which refered to their order on the original
1359 // file, the fPidOffset is to be added to those values to correctly find the
1360 // TProcessID. This fPidOffset needs to be increment if the key/basket is copied
1361 // and need to be zero for new key/basket.
1362 Long64_t pdir;
1363 b >> pdir;
1366 } else {
1370 }
1372 //the following test required for forward and backward compatibility
1373 if (fClassName == "TDirectory") {
1374 fClassName = "TDirectoryFile";
1376 }
1377 fName.Streamer(b);
1378 fTitle.Streamer(b);
1379 if (fKeylen < 0) {
1380 Error("Streamer","The value of fKeylen is incorrect (%d) ; trying to recover by setting it to zero",fKeylen);
1381 MakeZombie();
1382 fKeylen = 0;
1383 }
1384 if (fObjlen < 0) {
1385 Error("Streamer","The value of fObjlen is incorrect (%d) ; trying to recover by setting it to zero",fObjlen);
1386 MakeZombie();
1387 fObjlen = 0;
1388 }
1389 if (fNbytes < 0) {
1390 Error("Streamer","The value of fNbytes is incorrect (%d) ; trying to recover by setting it to zero",fNbytes);
1391 MakeZombie();
1392 fNbytes = 0;
1393 }
1394
1395 } else {
1396 b << fNbytes;
1398 b << version;
1399 b << fObjlen;
1400 if (fDatime.Get() == 0) fDatime.Set();
1402 TDatime((UInt_t) 1).Streamer(b);
1403 else
1405 b << fKeylen;
1406 b << fCycle;
1407 if (fVersion > 1000) {
1408 b << fSeekKey;
1409
1410 // We currently store in the 16 highest bit of fSeekPdir the value of
1411 // fPidOffset. This offset is used when a key (or basket) is transferred from one
1412 // file to the other. In this case the TRef and TObject might have stored a
1413 // pid index (to retrieve TProcessIDs) which refered to their order on the original
1414 // file, the fPidOffset is to be added to those values to correctly find the
1415 // TProcessID. This fPidOffset needs to be increment if the key/basket is copied
1416 // and need to be zero for new key/basket.
1418 b << pdir;
1419 } else {
1420 b << (Int_t)fSeekKey;
1421 b << (Int_t)fSeekPdir;
1422 }
1424 // We want to record "TDirectory" instead of TDirectoryFile so that the file can be read by ancient version of ROOT.
1425 b.WriteTString(gTDirectoryString);
1426 } else {
1428 }
1429 fName.Streamer(b);
1430 fTitle.Streamer(b);
1431 }
1432}
1433
1434////////////////////////////////////////////////////////////////////////////////
1435/// Write the encoded object supported by this key.
1436/// The function returns the number of bytes committed to the file.
1437/// If a write error occurs, the number of bytes returned is -1.
1438
1440{
1441 if (!f) f = GetFile();
1442 if (!f) return -1;
1443
1445 char *buffer = fBuffer;
1446 if (cycle) {
1447 fCycle = cycle;
1448 FillBuffer(buffer);
1449 buffer = fBuffer;
1450 }
1451
1452 if (fLeft > 0) nsize += sizeof(Int_t);
1453 f->Seek(fSeekKey);
1454 Bool_t result = f->WriteBuffer(buffer,nsize);
1455 //f->Flush(); Flushing takes too much time.
1456 // Let user flush the file when they want.
1457 if (gDebug) {
1458 std::cout <<" TKey Writing "<<nsize<< " bytes at address "<<fSeekKey
1459 <<" for ID= " <<GetName()<<" Title= "<<GetTitle()<<std::endl;
1460 }
1461
1462 DeleteBuffer();
1463 return result==kTRUE ? -1 : nsize;
1464}
1465
1466////////////////////////////////////////////////////////////////////////////////
1467/// Write the encoded object supported by this key.
1468/// The function returns the number of bytes committed to the file.
1469/// If a write error occurs, the number of bytes returned is -1.
1470
1472{
1473 if (!f) f = GetFile();
1474 if (!f) return -1;
1475
1477 char *buffer = fBuffer;
1478
1479 if (fLeft > 0) nsize += sizeof(Int_t);
1480 f->Seek(fSeekKey);
1481 Bool_t result = f->WriteBuffer(buffer,nsize);
1482 //f->Flush(); Flushing takes too much time.
1483 // Let user flush the file when they want.
1484 if (gDebug) {
1485 std::cout <<" TKey Writing "<<nsize<< " bytes at address "<<fSeekKey
1486 <<" for ID= " <<GetName()<<" Title= "<<GetTitle()<<std::endl;
1487 }
1488
1489 return result==kTRUE ? -1 : nsize;
1490}
1491
1492////////////////////////////////////////////////////////////////////////////////
1493/// Title can keep 32x32 xpm thumbnail/icon of the parent object.
1494
1495const char *TKey::GetIconName() const
1496{
1497 return (!fTitle.IsNull() && fTitle.BeginsWith("/* ") ? fTitle.Data() : 0);
1498}
1499
1500////////////////////////////////////////////////////////////////////////////////
1501/// Returns title (title can contain 32x32 xpm thumbnail/icon).
1502
1503const char *TKey::GetTitle() const
1504{
1505 if (!fTitle.IsNull() && fTitle.BeginsWith("/* ")) { // title contains xpm thumbnail
1506 static TString ret;
1507 int start = fTitle.Index("/*") + 3;
1508 int stop = fTitle.Index("*/") - 1;
1509 ret = fTitle(start, stop - start);
1510 return ret.Data();
1511 }
1512 return fTitle.Data();
1513}
void frombuf(char *&buf, Bool_t *x)
Definition Bytes.h:278
void tobuf(char *&buf, Bool_t x)
Definition Bytes.h:55
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
unsigned short UShort_t
Unsigned Short integer 2 bytes (unsigned short)
Definition RtypesCore.h:54
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:59
short Version_t
Class version identifier (short)
Definition RtypesCore.h:79
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char)
Definition RtypesCore.h:52
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
short Short_t
Signed Short integer 2 bytes (short)
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:84
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
const char Option_t
Option string (const char)
Definition RtypesCore.h:80
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
#define gFile
Definition TFile.h:439
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
char name[80]
Definition TGX11.cxx:110
const ULong64_t kPidOffsetMask
Definition TKey.cxx:73
static const TString gTDirectoryString("TDirectory")
const Int_t kTitleMax
Definition TKey.cxx:70
std::atomic< UInt_t > keyAbsNumber
Definition TKey.cxx:80
const UChar_t kPidOffsetShift
Definition TKey.cxx:77
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:627
#define gROOT
Definition TROOT.h:414
Int_t Sizeof() const override
Using a TBrowser one can browse all ROOT objects.
Definition TBrowser.h:37
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
Definition TBufferFile.h:47
Buffer base class used for serializing objects.
Definition TBuffer.h:43
void SetParent(TObject *parent)
Set parent owning this buffer.
Definition TBuffer.cxx:269
@ kWrite
Definition TBuffer.h:73
@ kRead
Definition TBuffer.h:73
void SetBufferOffset(Int_t offset=0)
Definition TBuffer.h:93
Int_t Length() const
Definition TBuffer.h:100
virtual void MapObject(const TObject *obj, UInt_t offset=1)=0
char * Buffer() const
Definition TBuffer.h:96
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
void Streamer(void *obj, TBuffer &b, const TClass *onfile_class=nullptr) const
Definition TClass.h:623
EState GetState() const
Definition TClass.h:501
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5017
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition TClass.cxx:5439
ROOT::DirAutoAdd_t GetDirectoryAutoAdd() const
Return the wrapper around the directory auto add function.
Definition TClass.cxx:7589
@ kDummyNew
Definition TClass.h:110
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition TClass.cxx:5980
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4901
Int_t GetBaseClassOffset(const TClass *toBase, void *address=nullptr, bool isDerivedObject=true)
Definition TClass.cxx:2796
Bool_t HasDefaultConstructor(Bool_t testio=kFALSE) const
Return true if we have access to a constructor usable for I/O.
Definition TClass.cxx:7487
@ kEmulated
Definition TClass.h:128
TClass * GetActualClass(const void *object) const
Return a pointer to the real class of the object.
Definition TClass.cxx:2612
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:2973
static TClass * Class()
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition TDatime.h:37
UInt_t Get() const
Return raw date/time as encoded by TDatime.
Definition TDatime.cxx:239
void FillBuffer(char *&buffer)
Encode Date/Time into buffer, used by I/O system.
Definition TDatime.cxx:228
Int_t Sizeof() const
Definition TDatime.h:81
virtual void Streamer(TBuffer &)
Stream a object of type TDatime.
Definition TDatime.cxx:415
void Set()
Set Date/Time to current time as reported by the system.
Definition TDatime.cxx:288
void ReadBuffer(char *&buffer)
Decode Date/Time from output buffer, used by I/O system.
Definition TDatime.cxx:277
A ROOT file is structured in Directories (like a file system).
static TClass * Class()
Describe directory structure in memory.
Definition TDirectory.h:45
virtual Long64_t GetSeekDir() const
Definition TDirectory.h:229
virtual TList * GetList() const
Definition TDirectory.h:223
virtual Int_t AppendKey(TKey *)
Definition TDirectory.h:185
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TFile * GetFile() const
Definition TDirectory.h:221
void SetName(const char *newname) override
Set the name for directory If the directory name is changed after the directory was written once,...
virtual void SetMother(TObject *mother)
Definition TDirectory.h:259
virtual TList * GetListOfKeys() const
Definition TDirectory.h:224
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:130
Int_t GetCompressionLevel() const
Definition TFile.h:483
virtual Long64_t GetEND() const
Definition TFile.h:319
virtual void MakeFree(Long64_t first, Long64_t last)
Mark unused bytes on the file.
Definition TFile.cxx:1473
Int_t GetCompressionAlgorithm() const
Definition TFile.h:477
@ kReproducible
Definition TFile.h:271
@ kStartBigFile
Definition TFile.h:278
Service class for TFile.
Definition TFree.h:27
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
const char * GetTitle() const override
Returns title (title can contain 32x32 xpm thumbnail/icon).
Definition TKey.cxx:1503
static constexpr Version_t Class_Version()
Definition TKey.h:118
void Delete(Option_t *option="") override
Delete an object from the file.
Definition TKey.cxx:571
@ kReproducible
Definition TKey.h:33
@ kIsDirectoryFile
Definition TKey.h:32
Int_t Sizeof() const override
Return the size in bytes of the key header structure.
Definition TKey.cxx:1325
TKey()
TKey default constructor.
Definition TKey.cxx:86
~TKey() override
TKey default destructor.
Definition TKey.cxx:558
TFile * GetFile() const
Returns file to which key belong.
Definition TKey.cxx:618
virtual void Keep()
Set the "KEEP" status.
Definition TKey.cxx:718
const char * GetIconName() const override
Title can keep 32x32 xpm thumbnail/icon of the parent object.
Definition TKey.cxx:1495
Int_t Read(const char *name) override
Read contents of object with specified name from the current directory.
Definition TKey.h:56
Int_t UnzipBuffer(char *targetBuffer, const char *compressedBuffer) const
Core of uncompressing the key payload.
Definition TKey.cxx:390
TDatime fDatime
Date/Time of insertion in file.
Definition TKey.h:44
TBuffer * fBufferRef
Pointer to the TBuffer object.
Definition TKey.h:52
UShort_t fPidOffset
!Offset to be added to the pid index in this key/buffer. This is actually saved in the high bits of f...
Definition TKey.h:53
virtual void IncrementPidOffset(UShort_t offset)
Increment fPidOffset by 'offset'.
Definition TKey.cxx:683
Short_t GetKeep() const
Returns the "KEEP" status.
Definition TKey.cxx:626
Int_t fVersion
Key version identifier.
Definition TKey.h:41
Bool_t IsFolder() const override
Check if object referenced by the key is a folder.
Definition TKey.cxx:697
Int_t fLeft
Number of bytes left in current segment.
Definition TKey.h:50
virtual const char * GetClassName() const
Definition TKey.h:77
Short_t fKeylen
Number of bytes for the key itself.
Definition TKey.h:45
virtual Bool_t ReadFile()
Read the key structure from the file.
Definition TKey.cxx:1257
void Browse(TBrowser *b) override
Read object from disk and call its Browse() method.
Definition TKey.cxx:460
virtual Int_t WriteFileKeepBuffer(TFile *f=nullptr)
Write the encoded object supported by this key.
Definition TKey.cxx:1471
Long64_t fSeekKey
Location of object on file.
Definition TKey.h:47
void Build(TDirectory *motherDir, const char *classname, Long64_t filepos)
Method used in all TKey constructor to initialize basic data fields.
Definition TKey.cxx:422
char * fBuffer
Object buffer.
Definition TKey.h:51
Long64_t fSeekPdir
Location of parent directory on file.
Definition TKey.h:48
virtual void SetParent(const TObject *parent)
Set parent in key buffer.
Definition TKey.cxx:1278
virtual void * ReadObjectAny(const TClass *expectedClass)
To read an object (non deriving from TObject) from the file.
Definition TKey.cxx:1030
void ReadKeyBuffer(char *&buffer)
Decode input buffer.
Definition TKey.cxx:1214
Int_t fNbytes
Number of bytes for the object on file.
Definition TKey.h:42
Int_t fObjlen
Length of uncompressed object in bytes.
Definition TKey.h:43
void Reset()
Reset the key as it had not been 'filled' yet.
Definition TKey.cxx:1286
Short_t fCycle
Cycle number.
Definition TKey.h:46
virtual TObject * ReadObjWithBuffer(char *bufferRead)
To read a TObject* from bufferRead.
Definition TKey.cxx:912
virtual void ls(Bool_t current) const
List Key contents.
Definition TKey.cxx:727
Short_t GetCycle() const
Return cycle number associated to this key.
Definition TKey.cxx:610
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition TKey.cxx:791
virtual void Create(Int_t nbytes, TFile *f=nullptr)
Create a TKey object of specified size.
Definition TKey.cxx:492
virtual void DeleteBuffer()
Delete key buffer(s).
Definition TKey.cxx:592
virtual Int_t WriteFile(Int_t cycle=1, TFile *f=nullptr)
Write the encoded object supported by this key.
Definition TKey.cxx:1439
virtual void ReadBuffer(char *&buffer)
Decode input buffer.
Definition TKey.cxx:1202
TDirectory * fMotherDir
!pointer to mother directory
Definition TKey.h:54
TString fClassName
Object Class name.
Definition TKey.h:49
void Print(Option_t *option="") const override
Print key contents.
Definition TKey.cxx:747
void FillBuffer(char *&buffer) override
Encode key header into output buffer.
Definition TKey.cxx:634
void Streamer(TBuffer &) override
Stream a class object.
Definition TKey.cxx:1342
A doubly linked list.
Definition TList.h:38
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:173
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
TString fTitle
Definition TNamed.h:33
TString fName
Definition TNamed.h:32
Mother of all ROOT objects.
Definition TObject.h:42
virtual Bool_t IsFolder() const
Returns kTRUE in case object contains browsable objects (like containers or lists of other objects).
Definition TObject.cxx:574
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:990
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1075
static TClass * Class()
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:882
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1089
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1117
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:893
virtual TClass * IsA() const
Definition TObject.h:248
void MakeZombie()
Definition TObject.h:55
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1063
static void IndentLevel()
Functions used by ls() to indent an object hierarchy.
Definition TROOT.cxx:2902
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
const char * Data() const
Definition TString.h:384
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition TString.cxx:1159
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition TString.h:632
Bool_t IsNull() const
Definition TString.h:422
virtual void FillBuffer(char *&buffer) const
Copy string into I/O buffer.
Definition TString.cxx:1316
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1418
virtual Int_t Sizeof() const
Returns size string will occupy on I/O buffer.
Definition TString.cxx:1407
virtual void ReadBuffer(char *&buffer)
Read string from I/O buffer.
Definition TString.cxx:1337
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:660
TF1 * f1
Definition legend1.C:11
void(* DirAutoAdd_t)(void *, TDirectory *)
Definition Rtypes.h:120
EValues
Note: this is only temporarily a struct and will become a enum class hence the name convention used.
Definition Compression.h:88