69 const Int_t kTitleMax = 32000;
71 const Int_t kMAXFILEBUFFER = 262144;
74 #if !defined(_MSC_VER) || (_MSC_VER>1300)
75 const ULong64_t kPidOffsetMask = 0xffffffffffffULL;
77 const ULong64_t kPidOffsetMask = 0xffffffffffffUL;
79 const UChar_t kPidOffsetShift = 48;
81 TString &gTDirectoryString() {
82 TTHREAD_TLS_DECL_ARG(TString,gTDirectoryString,
"TDirectory");
83 return gTDirectoryString;
85 std::atomic<UInt_t> keyAbsNumber{0};
92 TKey::TKey() : TNamed(), fDatime((UInt_t)0)
98 keyAbsNumber++; SetUniqueID(keyAbsNumber);
104 TKey::TKey(TDirectory* motherDir) : TNamed(), fDatime((UInt_t)0)
106 Build(motherDir,
"", 0);
110 keyAbsNumber++; SetUniqueID(keyAbsNumber);
116 TKey::TKey(TDirectory* motherDir,
const TKey &orig, UShort_t pidOffset) : TNamed(), fDatime((UInt_t)0)
118 fMotherDir = motherDir;
120 fPidOffset = orig.fPidOffset + pidOffset;
121 fNbytes = orig.fNbytes;
122 fObjlen = orig.fObjlen;
123 fClassName = orig.fClassName;
125 fTitle = orig.fTitle;
127 fCycle = fMotherDir->AppendKey(
this);
132 fVersion = TKey::Class_Version();
133 Long64_t filepos = GetFile()->GetEND();
134 if (filepos > TFile::kStartBigFile || fPidOffset) fVersion += 1000;
138 UInt_t bufferDecOffset = 0;
139 UInt_t bufferIncOffset = 0;
140 UInt_t alloc = fNbytes +
sizeof(Int_t);
141 if (fKeylen < orig.fKeylen) {
142 bufferDecOffset = orig.fKeylen - fKeylen;
143 fNbytes -= bufferDecOffset;
144 }
else if (fKeylen > orig.fKeylen) {
145 bufferIncOffset = fKeylen - orig.fKeylen;
146 alloc += bufferIncOffset;
147 fNbytes += bufferIncOffset;
150 fBufferRef =
new TBufferFile(TBuffer::kWrite, alloc);
151 fBuffer = fBufferRef->Buffer();
155 TFile* f = orig.GetFile();
157 Int_t nsize = orig.fNbytes;
158 f->Seek(orig.fSeekKey);
159 if( f->ReadBuffer(fBuffer+bufferIncOffset,nsize) )
161 Error(
"ReadFile",
"Failed to read data.");
165 std::cout <<
"TKey Reading "<<nsize<<
" bytes at address "<<fSeekKey<<std::endl;
168 fBuffer += bufferDecOffset;
169 Int_t nout = fNbytes - fKeylen;
171 fBufferRef->SetBufferOffset(bufferDecOffset);
172 Streamer(*fBufferRef);
180 TKey::TKey(Long64_t pointer, Int_t nbytes, TDirectory* motherDir) : TNamed()
182 Build(motherDir,
"", pointer);
186 fBuffer =
new char[nbytes];
187 keyAbsNumber++; SetUniqueID(keyAbsNumber);
196 TKey::TKey(
const char *name,
const char *title,
const TClass *cl, Int_t nbytes, TDirectory* motherDir)
199 Build(motherDir, cl->GetName(), -1);
212 TKey::TKey(
const TString &name,
const TString &title,
const TClass *cl, Int_t nbytes, TDirectory* motherDir)
215 Build(motherDir, cl->GetName(), -1);
228 TKey::TKey(
const TObject *obj,
const char *name, Int_t bufsize, TDirectory* motherDir)
229 : TNamed(name, obj->GetTitle())
233 if (!obj->IsA()->HasDefaultConstructor()) {
234 Warning(
"TKey",
"since %s has no public constructor\n"
235 "\twhich can be called without argument, objects of this class\n"
236 "\tcan not be read with the current library. You will need to\n"
237 "\tadd a default constructor before attempting to read it.",
241 Build(motherDir, obj->ClassName(), -1);
243 Int_t lbuf, nout, noutot, bufmax, nzip;
244 fBufferRef =
new TBufferFile(TBuffer::kWrite, bufsize);
245 fBufferRef->SetParent(GetFile());
246 fCycle = fMotherDir->AppendKey(
this);
248 Streamer(*fBufferRef);
249 fKeylen = fBufferRef->Length();
250 fBufferRef->MapObject(obj);
251 ((TObject*)obj)->Streamer(*fBufferRef);
252 lbuf = fBufferRef->Length();
253 fObjlen = lbuf - fKeylen;
255 Int_t cxlevel = GetFile() ? GetFile()->GetCompressionLevel() : 0;
256 ROOT::RCompressionSetting::EAlgorithm::EValues cxAlgorithm =
static_cast<ROOT::RCompressionSetting::EAlgorithm::EValues
>(GetFile() ? GetFile()->GetCompressionAlgorithm() : 0);
257 if (cxlevel > 0 && fObjlen > 256) {
258 Int_t nbuffers = 1 + (fObjlen - 1)/kMAXZIPBUF;
259 Int_t buflen = TMath::Max(512,fKeylen + fObjlen + 9*nbuffers + 28);
260 fBuffer =
new char[buflen];
261 char *objbuf = fBufferRef->Buffer() + fKeylen;
262 char *bufcur = &fBuffer[fKeylen];
265 for (Int_t i = 0; i < nbuffers; ++i) {
266 if (i == nbuffers - 1) bufmax = fObjlen - nzip;
267 else bufmax = kMAXZIPBUF;
268 R__zipMultipleAlgorithm(cxlevel, &bufmax, objbuf, &bufmax, bufcur, &nout, cxAlgorithm);
269 if (nout == 0 || nout >= fObjlen) {
270 fBuffer = fBufferRef->Buffer();
272 fBufferRef->SetBufferOffset(0);
273 Streamer(*fBufferRef);
278 objbuf += kMAXZIPBUF;
282 fBufferRef->SetBufferOffset(0);
283 Streamer(*fBufferRef);
284 memcpy(fBuffer,fBufferRef->Buffer(),fKeylen);
285 delete fBufferRef; fBufferRef = 0;
287 fBuffer = fBufferRef->Buffer();
289 fBufferRef->SetBufferOffset(0);
290 Streamer(*fBufferRef);
301 TKey::TKey(
const void *obj,
const TClass *cl,
const char *name, Int_t bufsize, TDirectory* motherDir)
302 : TNamed(name,
"object title")
304 R__ASSERT(obj && cl);
306 if (!cl->HasDefaultConstructor()) {
307 Warning(
"TKey",
"since %s has no public constructor\n"
308 "\twhich can be called without argument, objects of this class\n"
309 "\tcan not be read with the current library. You will need to\n"
310 "\tadd a default constructor before attempting to read it.",
314 TClass *clActual = cl->GetActualClass(obj);
315 const void* actualStart;
317 const char *temp = (
const char*) obj;
319 Int_t offset = (cl != clActual) ?
320 clActual->GetBaseClassOffset(cl) : 0;
326 clActual =
const_cast<TClass*
>(cl);
330 Build(motherDir, clActual->GetName(), -1);
332 fBufferRef =
new TBufferFile(TBuffer::kWrite, bufsize);
333 fBufferRef->SetParent(GetFile());
334 fCycle = fMotherDir->AppendKey(
this);
336 Streamer(*fBufferRef);
337 fKeylen = fBufferRef->Length();
339 Int_t lbuf, nout, noutot, bufmax, nzip;
341 fBufferRef->MapObject(actualStart,clActual);
342 clActual->Streamer((
void*)actualStart, *fBufferRef);
343 lbuf = fBufferRef->Length();
344 fObjlen = lbuf - fKeylen;
346 Int_t cxlevel = GetFile() ? GetFile()->GetCompressionLevel() : 0;
347 ROOT::RCompressionSetting::EAlgorithm::EValues cxAlgorithm =
static_cast<ROOT::RCompressionSetting::EAlgorithm::EValues
>(GetFile() ? GetFile()->GetCompressionAlgorithm() : 0);
348 if (cxlevel > 0 && fObjlen > 256) {
349 Int_t nbuffers = 1 + (fObjlen - 1)/kMAXZIPBUF;
350 Int_t buflen = TMath::Max(512,fKeylen + fObjlen + 9*nbuffers + 28);
351 fBuffer =
new char[buflen];
352 char *objbuf = fBufferRef->Buffer() + fKeylen;
353 char *bufcur = &fBuffer[fKeylen];
356 for (Int_t i = 0; i < nbuffers; ++i) {
357 if (i == nbuffers - 1) bufmax = fObjlen - nzip;
358 else bufmax = kMAXZIPBUF;
359 R__zipMultipleAlgorithm(cxlevel, &bufmax, objbuf, &bufmax, bufcur, &nout, cxAlgorithm);
360 if (nout == 0 || nout >= fObjlen) {
361 fBuffer = fBufferRef->Buffer();
363 fBufferRef->SetBufferOffset(0);
364 Streamer(*fBufferRef);
369 objbuf += kMAXZIPBUF;
373 fBufferRef->SetBufferOffset(0);
374 Streamer(*fBufferRef);
375 memcpy(fBuffer,fBufferRef->Buffer(),fKeylen);
376 delete fBufferRef; fBufferRef = 0;
378 fBuffer = fBufferRef->Buffer();
380 fBufferRef->SetBufferOffset(0);
381 Streamer(*fBufferRef);
391 void TKey::Build(TDirectory* motherDir,
const char* classname, Long64_t filepos)
393 fMotherDir = motherDir;
406 fClassName = classname;
408 if (fClassName ==
"TDirectoryFile") SetBit(kIsDirectoryFile);
410 fVersion = TKey::Class_Version();
412 if ((filepos==-1) && GetFile()) filepos = GetFile()->GetEND();
413 if (filepos > TFile::kStartBigFile) fVersion += 1000;
415 if (fTitle.Length() > kTitleMax) fTitle.Resize(kTitleMax);
417 if (GetFile() && GetFile()->TestBit(TFile::kReproducible))
418 SetBit(TKey::kReproducible);
429 void TKey::Browse(TBrowser *b)
431 if (fMotherDir==0)
return;
433 TClass *objcl = TClass::GetClass(GetClassName());
435 void* obj = fMotherDir->GetList()->FindObject(GetName());
436 if (obj && objcl->IsTObject()) {
437 TObject *tobj = (TObject*) objcl->DynamicCast(TObject::Class(), obj);
438 if (!tobj->IsFolder()) {
439 if (tobj->InheritsFrom(TCollection::Class()))
450 objcl->Browse(obj,b);
451 b->SetRefreshFlag(kTRUE);
461 void TKey::Create(Int_t nbytes, TFile* externFile)
463 keyAbsNumber++; SetUniqueID(keyAbsNumber);
465 TFile *f = externFile;
466 if (!f) f = GetFile();
468 Error(
"Create",
"Cannot create key without file");
472 Int_t nsize = nbytes + fKeylen;
473 TList *lfree = f->GetListOfFree();
474 TFree *f1 = (TFree*)lfree->First();
477 TFree *bestfree = f1->GetBestFree(lfree,nsize);
479 Error(
"Create",
"Cannot allocate %d bytes for ID = %s Title = %s",
480 nsize,GetName(),GetTitle());
484 if (f->TestBit(TFile::kReproducible))
485 SetBit(TKey::kReproducible);
488 fSeekKey = bestfree->GetFirst();
490 if (fSeekKey >= f->GetEND()) {
491 f->SetEND(fSeekKey+nsize);
492 bestfree->SetFirst(fSeekKey+nsize);
493 if (f->GetEND() > bestfree->GetLast()) {
494 bestfree->SetLast(bestfree->GetLast() + 1000000000);
497 if (!fBuffer) fBuffer =
new char[nsize];
499 fLeft = Int_t(bestfree->GetLast() - fSeekKey - nsize + 1);
505 fBuffer =
new char[nsize];
507 lfree->Remove(bestfree);
513 fBuffer =
new char[nsize+
sizeof(Int_t)];
515 char *buffer = fBuffer+nsize;
516 Int_t nbytesleft = -fLeft;
517 tobuf(buffer, nbytesleft);
518 bestfree->SetFirst(fSeekKey+nsize);
521 fSeekPdir = externFile ? externFile->GetSeekDir() : fMotherDir->GetSeekDir();
541 void TKey::Delete(Option_t *option)
543 if (option && option[0] ==
'v') printf(
"Deleting key: %s at address %lld, nbytes = %d\n",GetName(),fSeekKey,fNbytes);
544 Long64_t first = fSeekKey;
545 Long64_t last = fSeekKey + fNbytes -1;
546 if (GetFile()) GetFile()->MakeFree(first, last);
547 fMotherDir->GetListOfKeys()->Remove(
this);
553 void TKey::DeleteBuffer()
571 Short_t TKey::GetCycle()
const
573 return ((fCycle >0) ? fCycle : -fCycle);
579 TFile *TKey::GetFile()
const
581 return fMotherDir!=0 ? fMotherDir->GetFile() : gFile;
587 Short_t TKey::GetKeep()
const
589 return ((fCycle >0) ? 0 : 1);
595 void TKey::FillBuffer(
char *&buffer)
597 tobuf(buffer, fNbytes);
598 Version_t version = fVersion;
599 tobuf(buffer, version);
601 tobuf(buffer, fObjlen);
602 if (TestBit(TKey::kReproducible))
603 TDatime((UInt_t) 1).FillBuffer(buffer);
605 fDatime.FillBuffer(buffer);
606 tobuf(buffer, fKeylen);
607 tobuf(buffer, fCycle);
608 if (fVersion > 1000) {
609 tobuf(buffer, fSeekKey);
618 Long64_t pdir = (((Long64_t)fPidOffset)<<kPidOffsetShift) | (kPidOffsetMask & fSeekPdir);
621 tobuf(buffer, (Int_t)fSeekKey);
622 tobuf(buffer, (Int_t)fSeekPdir);
624 if (TestBit(kIsDirectoryFile)) {
626 gTDirectoryString().FillBuffer(buffer);
628 fClassName.FillBuffer(buffer);
630 fName.FillBuffer(buffer);
631 fTitle.FillBuffer(buffer);
644 void TKey::IncrementPidOffset(UShort_t offset)
646 fPidOffset += offset;
651 if (fVersion<1000) fVersion += 1000;
658 Bool_t TKey::IsFolder()
const
662 TClass *classPtr = TClass::GetClass((
const char *) fClassName);
663 if (classPtr && classPtr->GetState() > TClass::kEmulated && classPtr->IsTObject()) {
664 TObject *obj = (TObject *) classPtr->DynamicCast(TObject::Class(), classPtr->New(TClass::kDummyNew));
666 ret = obj->IsFolder();
681 if (fCycle >0) fCycle = -fCycle;
687 void TKey::ls(Option_t *)
const
689 TROOT::IndentLevel();
690 std::cout <<
"KEY: "<<fClassName<<
"\t"<<GetName()<<
";"<<GetCycle()<<
"\t"<<GetTitle()<<std::endl;
696 void TKey::Print(Option_t *)
const
698 printf(
"TKey Name = %s, Title = %s, Cycle = %d\n",GetName(),GetTitle(),GetCycle());
732 TObject *TKey::ReadObj()
734 TClass *cl = TClass::GetClass(fClassName.Data());
736 Error(
"ReadObj",
"Unknown class %s", fClassName.Data());
739 if (!cl->IsTObject()) {
741 return (TObject*)ReadObjectAny(0);
744 fBufferRef =
new TBufferFile(TBuffer::kRead, fObjlen+fKeylen);
746 Error(
"ReadObj",
"Cannot allocate buffer: fObjlen = %d", fObjlen);
749 if (GetFile()==0)
return 0;
750 fBufferRef->SetParent(GetFile());
751 fBufferRef->SetPidOffset(fPidOffset);
753 if (fObjlen > fNbytes-fKeylen) {
754 fBuffer =
new char[fNbytes];
763 memcpy(fBufferRef->Buffer(),fBuffer,fKeylen);
765 fBuffer = fBufferRef->Buffer();
775 fBufferRef->SetBufferOffset(
sizeof(fNbytes));
776 Version_t kvers = fBufferRef->ReadVersion();
778 fBufferRef->SetBufferOffset(fKeylen);
782 char *pobj = (
char*)cl->New();
784 Error(
"ReadObj",
"Cannot create new object of class %s", fClassName.Data());
787 Int_t baseOffset = cl->GetBaseClassOffset(TObject::Class());
788 if (baseOffset==-1) {
792 Fatal(
"ReadObj",
"Incorrect detection of the inheritance from TObject for class %s.\n",
795 tobj = (TObject*)(pobj+baseOffset);
797 fBufferRef->MapObject(pobj,cl);
799 if (fObjlen > fNbytes-fKeylen) {
800 char *objbuf = fBufferRef->Buffer() + fKeylen;
801 UChar_t *bufcur = (UChar_t *)&fBuffer[fKeylen];
802 Int_t nin, nout = 0, nbuf;
805 Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
807 R__unzip(&nin, bufcur, &nbuf, (
unsigned char*) objbuf, &nout);
810 if (noutot >= fObjlen)
break;
815 tobj->Streamer(*fBufferRef);
821 cl->Destructor(pobj);
827 tobj->Streamer(*fBufferRef);
830 if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
832 if (cl->InheritsFrom(TDirectoryFile::Class())) {
833 TDirectory *dir =
static_cast<TDirectoryFile*
>(tobj);
834 dir->SetName(GetName());
835 dir->SetTitle(GetTitle());
836 dir->SetMother(fMotherDir);
837 fMotherDir->Append(dir);
842 ROOT::DirAutoAdd_t addfunc = cl->GetDirectoryAutoAdd();
844 addfunc(pobj, fMotherDir);
874 TObject *TKey::ReadObjWithBuffer(
char *bufferRead)
877 TClass *cl = TClass::GetClass(fClassName.Data());
879 Error(
"ReadObjWithBuffer",
"Unknown class %s", fClassName.Data());
882 if (!cl->IsTObject()) {
884 return (TObject*)ReadObjectAny(0);
887 fBufferRef =
new TBufferFile(TBuffer::kRead, fObjlen+fKeylen);
889 Error(
"ReadObjWithBuffer",
"Cannot allocate buffer: fObjlen = %d", fObjlen);
892 if (GetFile()==0)
return 0;
893 fBufferRef->SetParent(GetFile());
894 fBufferRef->SetPidOffset(fPidOffset);
896 if (fObjlen > fNbytes-fKeylen) {
897 fBuffer = bufferRead;
898 memcpy(fBufferRef->Buffer(),fBuffer,fKeylen);
900 fBuffer = fBufferRef->Buffer();
905 fBufferRef->SetBufferOffset(
sizeof(fNbytes));
906 Version_t kvers = fBufferRef->ReadVersion();
908 fBufferRef->SetBufferOffset(fKeylen);
912 char *pobj = (
char*)cl->New();
914 Error(
"ReadObjWithBuffer",
"Cannot create new object of class %s", fClassName.Data());
917 Int_t baseOffset = cl->GetBaseClassOffset(TObject::Class());
918 if (baseOffset==-1) {
922 Fatal(
"ReadObjWithBuffer",
"Incorrect detection of the inheritance from TObject for class %s.\n",
925 tobj = (TObject*)(pobj+baseOffset);
928 fBufferRef->MapObject(pobj,cl);
930 if (fObjlen > fNbytes-fKeylen) {
931 char *objbuf = fBufferRef->Buffer() + fKeylen;
932 UChar_t *bufcur = (UChar_t *)&fBuffer[fKeylen];
933 Int_t nin, nout = 0, nbuf;
936 Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
938 R__unzip(&nin, bufcur, &nbuf, (
unsigned char*) objbuf, &nout);
941 if (noutot >= fObjlen)
break;
946 tobj->Streamer(*fBufferRef);
950 cl->Destructor(pobj);
956 tobj->Streamer(*fBufferRef);
959 if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
961 if (cl->InheritsFrom(TDirectoryFile::Class())) {
962 TDirectory *dir =
static_cast<TDirectoryFile*
>(tobj);
963 dir->SetName(GetName());
964 dir->SetTitle(GetTitle());
965 dir->SetMother(fMotherDir);
966 fMotherDir->Append(dir);
971 ROOT::DirAutoAdd_t addfunc = cl->GetDirectoryAutoAdd();
973 addfunc(pobj, fMotherDir);
1010 void *TKey::ReadObjectAny(
const TClass* expectedClass)
1012 fBufferRef =
new TBufferFile(TBuffer::kRead, fObjlen+fKeylen);
1014 Error(
"ReadObj",
"Cannot allocate buffer: fObjlen = %d", fObjlen);
1017 if (GetFile()==0)
return 0;
1018 fBufferRef->SetParent(GetFile());
1019 fBufferRef->SetPidOffset(fPidOffset);
1021 if (fObjlen > fNbytes-fKeylen) {
1022 fBuffer =
new char[fNbytes];
1024 memcpy(fBufferRef->Buffer(),fBuffer,fKeylen);
1026 fBuffer = fBufferRef->Buffer();
1031 fBufferRef->SetBufferOffset(
sizeof(fNbytes));
1032 Version_t kvers = fBufferRef->ReadVersion();
1034 fBufferRef->SetBufferOffset(fKeylen);
1035 TClass *cl = TClass::GetClass(fClassName.Data());
1036 TClass *clOnfile = 0;
1038 Error(
"ReadObjectAny",
"Unknown class %s", fClassName.Data());
1041 Int_t baseOffset = 0;
1042 if (expectedClass) {
1044 baseOffset = cl->GetBaseClassOffset(expectedClass);
1045 if (baseOffset == -1) {
1048 if (!expectedClass->GetSchemaRules() ||
1049 !expectedClass->GetSchemaRules()->HasRuleWithSourceClass(cl->GetName()))
1056 cl =
const_cast<TClass*
>(expectedClass);
1057 Info(
"ReadObjectAny",
"Using Converter StreamerInfo from %s to %s",clOnfile->GetName(),expectedClass->GetName());
1059 if (cl->GetState() > TClass::kEmulated && expectedClass->GetState() <= TClass::kEmulated) {
1061 Warning(
"ReadObjectAny",
1062 "Trying to read an emulated class (%s) to store in a compiled pointer (%s)",
1063 cl->GetName(),expectedClass->GetName());
1068 void *pobj = cl->New();
1070 Error(
"ReadObjectAny",
"Cannot create new object of class %s", fClassName.Data());
1075 fBufferRef->MapObject(pobj,cl);
1077 if (fObjlen > fNbytes-fKeylen) {
1078 char *objbuf = fBufferRef->Buffer() + fKeylen;
1079 UChar_t *bufcur = (UChar_t *)&fBuffer[fKeylen];
1080 Int_t nin, nout = 0, nbuf;
1083 Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
1085 R__unzip(&nin, bufcur, &nbuf, (
unsigned char*) objbuf, &nout);
1088 if (noutot >= fObjlen)
break;
1093 cl->Streamer((
void*)pobj, *fBufferRef, clOnfile);
1097 cl->Destructor(pobj);
1102 cl->Streamer((
void*)pobj, *fBufferRef, clOnfile);
1105 if (cl->IsTObject()) {
1106 auto tobjBaseOffset = cl->GetBaseClassOffset(TObject::Class());
1107 if (tobjBaseOffset == -1) {
1108 Fatal(
"ReadObj",
"Incorrect detection of the inheritance from TObject for class %s.\n",
1111 TObject *tobj = (TObject*)( ((
char*)pobj) + tobjBaseOffset);
1114 if (gROOT->GetForceStyle()) tobj->UseCurrentStyle();
1116 if (cl->InheritsFrom(TDirectoryFile::Class())) {
1117 TDirectory *dir =
static_cast<TDirectoryFile*
>(tobj);
1118 dir->SetName(GetName());
1119 dir->SetTitle(GetTitle());
1120 dir->SetMother(fMotherDir);
1121 fMotherDir->Append(dir);
1127 ROOT::DirAutoAdd_t addfunc = cl->GetDirectoryAutoAdd();
1129 addfunc(pobj, fMotherDir);
1138 return ( ((
char*)pobj) + baseOffset );
1148 Int_t TKey::Read(TObject *obj)
1150 if (!obj || (GetFile()==0))
return 0;
1152 fBufferRef =
new TBufferFile(TBuffer::kRead, fObjlen+fKeylen);
1153 fBufferRef->SetParent(GetFile());
1154 fBufferRef->SetPidOffset(fPidOffset);
1157 fBufferRef->MapObject(obj);
1159 if (fObjlen > fNbytes-fKeylen) {
1160 fBuffer =
new char[fNbytes];
1162 memcpy(fBufferRef->Buffer(),fBuffer,fKeylen);
1164 fBuffer = fBufferRef->Buffer();
1167 fBufferRef->SetBufferOffset(fKeylen);
1168 if (fObjlen > fNbytes-fKeylen) {
1169 char *objbuf = fBufferRef->Buffer() + fKeylen;
1170 UChar_t *bufcur = (UChar_t *)&fBuffer[fKeylen];
1171 Int_t nin, nout = 0, nbuf;
1174 Int_t hc = R__unzip_header(&nin, bufcur, &nbuf);
1176 R__unzip(&nin, bufcur, &nbuf, (
unsigned char*) objbuf, &nout);
1179 if (noutot >= fObjlen)
break;
1183 if (nout) obj->Streamer(*fBufferRef);
1186 obj->Streamer(*fBufferRef);
1191 ROOT::DirAutoAdd_t addfunc = obj->IsA()->GetDirectoryAutoAdd();
1193 addfunc(obj, fMotherDir);
1208 void TKey::ReadBuffer(
char *&buffer)
1210 ReadKeyBuffer(buffer);
1212 if (!gROOT->ReadingObject() && gDirectory) {
1213 if (fSeekPdir != gDirectory->GetSeekDir()) gDirectory->AppendKey(
this);
1220 void TKey::ReadKeyBuffer(
char *&buffer)
1222 frombuf(buffer, &fNbytes);
1224 frombuf(buffer,&version);
1225 fVersion = (Int_t)version;
1226 frombuf(buffer, &fObjlen);
1227 fDatime.ReadBuffer(buffer);
1228 frombuf(buffer, &fKeylen);
1229 frombuf(buffer, &fCycle);
1230 if (fVersion > 1000) {
1231 frombuf(buffer, &fSeekKey);
1241 frombuf(buffer, &pdir);
1242 fPidOffset = pdir >> kPidOffsetShift;
1243 fSeekPdir = pdir & kPidOffsetMask;
1245 UInt_t seekkey,seekdir;
1246 frombuf(buffer, &seekkey); fSeekKey = (Long64_t)seekkey;
1247 frombuf(buffer, &seekdir); fSeekPdir= (Long64_t)seekdir;
1249 fClassName.ReadBuffer(buffer);
1251 if (fClassName ==
"TDirectory") {
1252 fClassName =
"TDirectoryFile";
1253 SetBit(kIsDirectoryFile);
1256 fName.ReadBuffer(buffer);
1257 fTitle.ReadBuffer(buffer);
1263 Bool_t TKey::ReadFile()
1265 TFile* f = GetFile();
1266 if (f==0)
return kFALSE;
1268 Int_t nsize = fNbytes;
1271 for (Int_t i = 0; i < nsize; i += kMAXFILEBUFFER) {
1272 int nb = kMAXFILEBUFFER;
1273 if (i+nb > nsize) nb = nsize - i;
1274 f->ReadBuffer(fBuffer+i,nb);
1277 if( f->ReadBuffer(fBuffer,nsize) )
1279 Error(
"ReadFile",
"Failed to read data.");
1284 std::cout <<
"TKey Reading "<<nsize<<
" bytes at address "<<fSeekKey<<std::endl;
1292 void TKey::SetParent(
const TObject *parent)
1294 if (fBufferRef) fBufferRef->SetParent((TObject*)parent);
1310 fDatime = (UInt_t)0;
1314 keyAbsNumber++; SetUniqueID(keyAbsNumber);
1334 Int_t TKey::Sizeof()
const
1336 Int_t nbytes = 22;
if (fVersion > 1000) nbytes += 8;
1337 nbytes += fDatime.Sizeof();
1338 if (TestBit(kIsDirectoryFile)) {
1341 nbytes += fClassName.Sizeof();
1343 nbytes += fName.Sizeof();
1344 nbytes += fTitle.Sizeof();
1351 void TKey::Streamer(TBuffer &b)
1354 if (b.IsReading()) {
1356 b >> version; fVersion = (Int_t)version;
1358 fDatime.Streamer(b);
1361 if (fVersion > 1000) {
1373 fPidOffset = pdir >> kPidOffsetShift;
1374 fSeekPdir = pdir & kPidOffsetMask;
1376 UInt_t seekkey, seekdir;
1377 b >> seekkey; fSeekKey = (Long64_t)seekkey;
1378 b >> seekdir; fSeekPdir= (Long64_t)seekdir;
1380 fClassName.Streamer(b);
1382 if (fClassName ==
"TDirectory") {
1383 fClassName =
"TDirectoryFile";
1384 SetBit(kIsDirectoryFile);
1389 Error(
"Streamer",
"The value of fKeylen is incorrect (%d) ; trying to recover by setting it to zero",fKeylen);
1394 Error(
"Streamer",
"The value of fObjlen is incorrect (%d) ; trying to recover by setting it to zero",fObjlen);
1399 Error(
"Streamer",
"The value of fNbytes is incorrect (%d) ; trying to recover by setting it to zero",fNbytes);
1406 version = (Version_t)fVersion;
1409 if (fDatime.Get() == 0) fDatime.Set();
1410 if (TestBit(TKey::kReproducible))
1411 TDatime((UInt_t) 1).Streamer(b);
1413 fDatime.Streamer(b);
1416 if (fVersion > 1000) {
1426 Long64_t pdir = (((Long64_t)fPidOffset)<<kPidOffsetShift) | (kPidOffsetMask & fSeekPdir);
1429 b << (Int_t)fSeekKey;
1430 b << (Int_t)fSeekPdir;
1432 if (TestBit(kIsDirectoryFile)) {
1434 gTDirectoryString().Streamer(b);
1436 fClassName.Streamer(b);
1448 Int_t TKey::WriteFile(Int_t cycle, TFile* f)
1450 if (!f) f = GetFile();
1453 Int_t nsize = fNbytes;
1454 char *buffer = fBuffer;
1461 if (fLeft > 0) nsize +=
sizeof(Int_t);
1464 for (Int_t i=0;i<nsize;i+=kMAXFILEBUFFER) {
1465 Int_t nb = kMAXFILEBUFFER;
1466 if (i+nb > nsize) nb = nsize - i;
1467 f->WriteBuffer(buffer,nb);
1471 Bool_t result = f->WriteBuffer(buffer,nsize);
1476 std::cout <<
" TKey Writing "<<nsize<<
" bytes at address "<<fSeekKey
1477 <<
" for ID= " <<GetName()<<
" Title= "<<GetTitle()<<std::endl;
1481 return result==kTRUE ? -1 : nsize;
1489 Int_t TKey::WriteFileKeepBuffer(TFile *f)
1491 if (!f) f = GetFile();
1494 Int_t nsize = fNbytes;
1495 char *buffer = fBuffer;
1497 if (fLeft > 0) nsize +=
sizeof(Int_t);
1500 for (Int_t i=0;i<nsize;i+=kMAXFILEBUFFER) {
1501 Int_t nb = kMAXFILEBUFFER;
1502 if (i+nb > nsize) nb = nsize - i;
1503 f->WriteBuffer(buffer,nb);
1507 Bool_t result = f->WriteBuffer(buffer,nsize);
1512 std::cout <<
" TKey Writing "<<nsize<<
" bytes at address "<<fSeekKey
1513 <<
" for ID= " <<GetName()<<
" Title= "<<GetTitle()<<std::endl;
1516 return result==kTRUE ? -1 : nsize;
1522 const char *TKey::GetIconName()
const
1524 return (!fTitle.IsNull() && fTitle.BeginsWith(
"/* ") ? fTitle.Data() : 0);
1530 const char *TKey::GetTitle()
const
1532 if (!fTitle.IsNull() && fTitle.BeginsWith(
"/* ")) {
1534 int start = fTitle.Index(
"/*") + 3;
1535 int stop = fTitle.Index(
"*/") - 1;
1536 ret = fTitle(start, stop - start);
1539 return fTitle.Data();