Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TStreamerInfoReadBuffer.cxx
Go to the documentation of this file.
1// @(#)root/io:$Id$
2// Author: Rene Brun 12/10/2000
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#include "TBuffer.h"
13#include "TFile.h"
14#include "TClass.h"
15#include "TBufferFile.h"
16#include "TClonesArray.h"
17#include "TError.h"
18#include "TRef.h"
19#include "TProcessID.h"
20#include "TStreamer.h"
21#include "TStreamerElement.h"
22#include "TStreamerInfo.h"
25#include "TVirtualArray.h"
26#include "TVirtualObject.h"
27#include "ThreadLocalStorage.h"
28
29// GetCurrentElement.
30// Currently only used by TRef::Streamer.
31
33{
34 //Pointer to current TStreamerElement
35 //Thread local storage.
36
37 TTHREAD_TLS(TStreamerElement*) fgElement(0);
38
39 return fgElement;
40}
41
42////////////////////////////////////////////////////////////////////////////////
43///static function returning a pointer to the current TStreamerElement
44///fgElement points to the current TStreamerElement being read in ReadBuffer
45
47{
48 return CurrentElement();
49}
50
51//==========CPP macros
52
53#define DOLOOP for(Int_t k=0; k<narr; ++k)
54
55#define ReadBasicTypeElem(name,index) \
56 { \
57 name *x=(name*)(arr[index]+ioffset); \
58 b >> *x; \
59 }
60
61#define ReadBasicType(name) \
62 { \
63 ReadBasicTypeElem(name,0); \
64 }
65
66#define ReadBasicTypeLoop(name) \
67 { \
68 for(Int_t k=0; k<narr; ++k) ReadBasicTypeElem(name,k); \
69 }
70
71#define ReadBasicArrayElem(name,index) \
72 { \
73 name *x=(name*)(arr[index]+ioffset); \
74 b.ReadFastArray(x,compinfo[i]->fLength); \
75 }
76
77#define ReadBasicArray(name) \
78 { \
79 ReadBasicArrayElem(name,0); \
80 }
81
82#define ReadBasicArrayLoop(name) \
83 { \
84 for(Int_t k=0; k<narr; ++k) ReadBasicArrayElem(name,k) \
85 }
86
87#define ReadBasicPointerElem(name,index) \
88 { \
89 Char_t isArray; \
90 b >> isArray; \
91 Int_t *l = (Int_t*)(arr[index]+imethod); \
92 if (*l < 0 || *l > b.BufferSize()) continue; \
93 name **f = (name**)(arr[index]+ioffset); \
94 int j; \
95 if (isArray) for(j=0;j<compinfo[i]->fLength;j++) { \
96 delete [] f[j]; \
97 f[j] = 0; if (*l <=0) continue; \
98 f[j] = new name[*l]; \
99 b.ReadFastArray(f[j],*l); \
100 } \
101 else for(j=0;j<compinfo[i]->fLength;j++) { \
102 delete [] f[j]; \
103 f[j] = 0; \
104 } \
105 }
106
107#define ReadBasicPointer(name) \
108 { \
109 const int imethod = compinfo[i]->fMethod+eoffset; \
110 ReadBasicPointerElem(name,0); \
111 }
112
113#define ReadBasicPointerLoop(name) \
114 { \
115 int imethod = compinfo[i]->fMethod+eoffset; \
116 for(int k=0; k<narr; ++k) { \
117 ReadBasicPointerElem(name,k); \
118 } \
119 }
120
121#define SkipCBasicType(name) \
122 { \
123 name dummy; \
124 DOLOOP{ b >> dummy; } \
125 break; \
126 }
127
128#define SkipCFloat16(name) \
129 { \
130 name dummy; \
131 DOLOOP { b.ReadFloat16(&dummy,aElement); } \
132 break; \
133 }
134
135#define SkipCDouble32(name) \
136 { \
137 name dummy; \
138 DOLOOP { b.ReadDouble32(&dummy,aElement); }\
139 break; \
140 }
141
142#define SkipCBasicArray(name,ReadArrayFunc) \
143 { \
144 name* readbuf = new name[compinfo->fLength]; \
145 DOLOOP { \
146 b.ReadArrayFunc(readbuf, compinfo->fLength); \
147 } \
148 delete[] readbuf; \
149 break; \
150 }
151
152#define SkipCBasicPointer(name,ReadArrayFunc) \
153 { \
154 Int_t addCounter = -111; \
155 if ((imethod>0) && (compinfo->fMethod>0)) addCounter = -1; \
156 if((addCounter<-1) && (aElement!=0) && (aElement->IsA()==TStreamerBasicPointer::Class())) { \
157 TStreamerElement* elemCounter = (TStreamerElement*) thisVar->GetElements()->FindObject(((TStreamerBasicPointer*)aElement)->GetCountName()); \
158 if (elemCounter) addCounter = elemCounter->GetTObjectOffset(); \
159 } \
160 if (addCounter>=-1) { \
161 int len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
162 Char_t isArray; \
163 DOLOOP { \
164 b >> isArray; \
165 char *arr_k = arr[k]; \
166 Int_t *l = (addCounter==-1 && arr_k) ? (Int_t*)(arr_k+imethod) : &addCounter; \
167 if (*l>0) { \
168 name* readbuf = new name[*l]; \
169 for (int j=0;j<len;j++) \
170 b.ReadArrayFunc(readbuf, *l); \
171 delete[] readbuf; \
172 } \
173 } \
174 } \
175 break; \
176 }
177
178////////////////////////////////////////////////////////////////////////////////
179/// Skip an element.
180
181template <class T>
182Int_t TStreamerInfo::ReadBufferSkip(TBuffer &b, const T &arr, const TCompInfo *compinfo, Int_t kase,
183 TStreamerElement *aElement, Int_t narr,
184 Int_t eoffset)
185{
186 TStreamerInfo* thisVar = this;
187
188 // Skip elements in a TClonesArray
189
190 TClass* cle = compinfo->fClass;
191
192 Int_t imethod = compinfo->fMethod+eoffset;
193
194 switch (kase) {
195
196 // skip basic types
213 UInt_t dummy;
214 DOLOOP{
215 b >> dummy;
216 if ((dummy & kIsReferenced) != 0) {
217 UShort_t pidf;
218 b >> pidf;
219 }
220 }
221 break;
222 }
223
224 // skip array of basic types array[8]
240
241 // skip pointer to an array of basic types array[n]
257
258 // skip char*
260 DOLOOP {
261 Int_t nch; b >> nch;
262 if (nch>0) {
263 char* readbuf = new char[nch];
264 b.ReadFastArray(readbuf,nch);
265 delete[] readbuf;
266 }
267 }
268 break;
269 }
270
271 // skip Class* derived from TObject
273 DOLOOP{
274 for (Int_t j=0;j<compinfo->fLength;j++) {
275 b.SkipObjectAny();
276 }
277 }
278 break;
279 }
280
281 // skip array counter //[n]
283 DOLOOP {
284 Int_t dummy; b >> dummy;
285 aElement->SetTObjectOffset(dummy);
286 }
287 break;
288 }
289
290 // skip Class * derived from TObject with comment field //->
291 // skip Class derived from TObject
294 if (cle == TRef::Class()) {
295 TRef refjunk;
296 DOLOOP{ refjunk.Streamer(b);}
297 } else {
298 DOLOOP{
299 b.SkipObjectAny();
300 }
301 }
302 break;
303 }
304
305 // skip Special case for TString, TObject, TNamed
307 TString s;
308 DOLOOP {
309 s.Streamer(b);
310 }
311 break;
312 }
314 TObject x;
315 DOLOOP {
316 x.Streamer(b);
317 }
318 break;
319 }
321 TNamed n;
322 DOLOOP {
323 n.Streamer(b);
324 }
325 break;
326 }
327
328 // skip Class * not derived from TObject with comment field //->
330 DOLOOP {
331 b.SkipObjectAny();
332 }
333 break;
334 }
335
336 // skip Class* not derived from TObject
338 DOLOOP {
339 for (Int_t j=0;j<compinfo->fLength;j++) {
340 b.SkipObjectAny();
341 }
342 }
343 break;
344 }
345
346 // skip Any Class not derived from TObject
348 DOLOOP {
349 b.SkipObjectAny();
350 }
351 break;
352 }
353
354 // skip Any Class not derived from TObject
358 if (fOldVersion<3) return 0;
359 b.SkipObjectAny();
360 break;
361 }
362
363 // skip Base Class
365 DOLOOP {
366 b.SkipObjectAny();
367 }
368 break;
369 }
370
373 DOLOOP {
374 b.SkipObjectAny();
375 }
376 break;
377 }
378 default:
379 //Error("ReadBufferClones","The element type %d is not supported yet\n",compinfo->fType);
380 return -1;
381 }
382 return 0;
383}
384
385#define ConvCBasicType(name,stream) \
386 { \
387 DOLOOP { \
388 name u; \
389 stream; \
390 switch(compinfo->fNewType) { \
391 case TStreamerInfo::kBool: {Bool_t *x=(Bool_t*)(arr[k]+ioffset); *x = (Bool_t)u; break;} \
392 case TStreamerInfo::kChar: {Char_t *x=(Char_t*)(arr[k]+ioffset); *x = (Char_t)u; break;} \
393 case TStreamerInfo::kShort: {Short_t *x=(Short_t*)(arr[k]+ioffset); *x = (Short_t)u; break;} \
394 case TStreamerInfo::kInt: {Int_t *x=(Int_t*)(arr[k]+ioffset); *x = (Int_t)u; break;} \
395 case TStreamerInfo::kLong: {Long_t *x=(Long_t*)(arr[k]+ioffset); *x = (Long_t)u; break;} \
396 case TStreamerInfo::kLong64: {Long64_t *x=(Long64_t*)(arr[k]+ioffset); *x = (Long64_t)u; break;} \
397 case TStreamerInfo::kFloat: {Float_t *x=(Float_t*)(arr[k]+ioffset); *x = (Float_t)u; break;} \
398 case TStreamerInfo::kFloat16: {Float_t *x=(Float_t*)(arr[k]+ioffset); *x = (Float_t)u; break;} \
399 case TStreamerInfo::kDouble: {Double_t *x=(Double_t*)(arr[k]+ioffset); *x = (Double_t)u; break;} \
400 case TStreamerInfo::kDouble32:{Double_t *x=(Double_t*)(arr[k]+ioffset); *x = (Double_t)u; break;} \
401 case TStreamerInfo::kUChar: {UChar_t *x=(UChar_t*)(arr[k]+ioffset); *x = (UChar_t)u; break;} \
402 case TStreamerInfo::kUShort: {UShort_t *x=(UShort_t*)(arr[k]+ioffset); *x = (UShort_t)u; break;} \
403 case TStreamerInfo::kUInt: {UInt_t *x=(UInt_t*)(arr[k]+ioffset); *x = (UInt_t)u; break;} \
404 case TStreamerInfo::kULong: {ULong_t *x=(ULong_t*)(arr[k]+ioffset); *x = (ULong_t)u; break;} \
405 case TStreamerInfo::kULong64: {ULong64_t*x=(ULong64_t*)(arr[k]+ioffset);*x = (ULong64_t)u;break;} \
406 } \
407 } break; \
408 }
409
410#define ConvCBasicArrayTo(newtype) \
411 { \
412 newtype *f=(newtype*)(arr[k]+ioffset); \
413 for (j=0;j<len;j++) f[j] = (newtype)readbuf[j]; \
414 break; \
415 }
416
417#define ConvCBasicArray(name,ReadArrayFunc) \
418 { \
419 int j, len = compinfo->fLength; \
420 name* readbuf = new name[len]; \
421 int newtype = compinfo->fNewType%20; \
422 DOLOOP { \
423 b.ReadArrayFunc(readbuf, len); \
424 switch(newtype) { \
425 case TStreamerInfo::kBool: ConvCBasicArrayTo(Bool_t); \
426 case TStreamerInfo::kChar: ConvCBasicArrayTo(Char_t); \
427 case TStreamerInfo::kShort: ConvCBasicArrayTo(Short_t); \
428 case TStreamerInfo::kInt: ConvCBasicArrayTo(Int_t); \
429 case TStreamerInfo::kLong: ConvCBasicArrayTo(Long_t); \
430 case TStreamerInfo::kLong64: ConvCBasicArrayTo(Long64_t); \
431 case TStreamerInfo::kFloat: ConvCBasicArrayTo(Float_t); \
432 case TStreamerInfo::kFloat16: ConvCBasicArrayTo(Float_t); \
433 case TStreamerInfo::kDouble: ConvCBasicArrayTo(Double_t); \
434 case TStreamerInfo::kDouble32: ConvCBasicArrayTo(Double_t); \
435 case TStreamerInfo::kUChar: ConvCBasicArrayTo(UChar_t); \
436 case TStreamerInfo::kUShort: ConvCBasicArrayTo(UShort_t); \
437 case TStreamerInfo::kUInt: ConvCBasicArrayTo(UInt_t); \
438 case TStreamerInfo::kULong: ConvCBasicArrayTo(ULong_t); \
439 case TStreamerInfo::kULong64: ConvCBasicArrayTo(ULong64_t); \
440 } \
441 } \
442 delete[] readbuf; \
443 break; \
444 }
445
446#define ConvCBasicPointerToOutOfRange(newtype,ReadArrayFunc) \
447 { \
448 newtype **f=(newtype**)(arr[k]+ioffset); \
449 for (j=0;j<len;j++) { \
450 delete [] f[j]; \
451 f[j] = 0; \
452 } \
453 break; \
454 }
455
456#define ConvCBasicPointerTo(newtype,ReadArrayFunc) \
457 { \
458 newtype **f=(newtype**)(arr[k]+ioffset); \
459 for (j=0;j<len;j++) { \
460 delete [] f[j]; \
461 f[j] = new newtype[*l]; \
462 newtype *af = f[j]; \
463 b.ReadArrayFunc(readbuf, *l); \
464 for (jj=0;jj<*l;jj++) af[jj] = (newtype)readbuf[jj]; \
465 } \
466 break; \
467 }
468
469#define ConvCBasicPointer(name,ReadArrayFunc) \
470 { \
471 Char_t isArray; \
472 int j, jj, len = aElement->GetArrayDim()?aElement->GetArrayLength():1; \
473 name* readbuf = 0; \
474 int newtype = compinfo->fNewType %20; \
475 Int_t imethod = compinfo->fMethod+eoffset; \
476 DOLOOP { \
477 b >> isArray; \
478 Int_t *l = (Int_t*)(arr[k]+imethod); \
479 if (*l>0 && *l < b.BufferSize()) { \
480 readbuf = new name[*l]; \
481 switch(newtype) { \
482 case TStreamerInfo::kBool: ConvCBasicPointerTo(Bool_t,ReadArrayFunc); \
483 case TStreamerInfo::kChar: ConvCBasicPointerTo(Char_t,ReadArrayFunc); \
484 case TStreamerInfo::kShort: ConvCBasicPointerTo(Short_t,ReadArrayFunc); \
485 case TStreamerInfo::kInt: ConvCBasicPointerTo(Int_t,ReadArrayFunc); \
486 case TStreamerInfo::kLong: ConvCBasicPointerTo(Long_t,ReadArrayFunc); \
487 case TStreamerInfo::kLong64: ConvCBasicPointerTo(Long64_t,ReadArrayFunc); \
488 case TStreamerInfo::kFloat: ConvCBasicPointerTo(Float_t,ReadArrayFunc); \
489 case TStreamerInfo::kFloat16: ConvCBasicPointerTo(Float_t,ReadArrayFunc); \
490 case TStreamerInfo::kDouble: ConvCBasicPointerTo(Double_t,ReadArrayFunc); \
491 case TStreamerInfo::kDouble32: ConvCBasicPointerTo(Double_t,ReadArrayFunc); \
492 case TStreamerInfo::kUChar: ConvCBasicPointerTo(UChar_t,ReadArrayFunc); \
493 case TStreamerInfo::kUShort: ConvCBasicPointerTo(UShort_t,ReadArrayFunc); \
494 case TStreamerInfo::kUInt: ConvCBasicPointerTo(UInt_t,ReadArrayFunc); \
495 case TStreamerInfo::kULong: ConvCBasicPointerTo(ULong_t,ReadArrayFunc); \
496 case TStreamerInfo::kULong64: ConvCBasicPointerTo(ULong64_t,ReadArrayFunc); \
497 } \
498 delete[] readbuf; \
499 } else { \
500 switch(newtype) { \
501 case TStreamerInfo::kBool: ConvCBasicPointerToOutOfRange(Bool_t,ReadArrayFunc); \
502 case TStreamerInfo::kChar: ConvCBasicPointerToOutOfRange(Char_t,ReadArrayFunc); \
503 case TStreamerInfo::kShort: ConvCBasicPointerToOutOfRange(Short_t,ReadArrayFunc); \
504 case TStreamerInfo::kInt: ConvCBasicPointerToOutOfRange(Int_t,ReadArrayFunc); \
505 case TStreamerInfo::kLong: ConvCBasicPointerToOutOfRange(Long_t,ReadArrayFunc); \
506 case TStreamerInfo::kLong64: ConvCBasicPointerToOutOfRange(Long64_t,ReadArrayFunc); \
507 case TStreamerInfo::kFloat: ConvCBasicPointerToOutOfRange(Float_t,ReadArrayFunc); \
508 case TStreamerInfo::kFloat16: ConvCBasicPointerToOutOfRange(Float_t,ReadArrayFunc); \
509 case TStreamerInfo::kDouble: ConvCBasicPointerToOutOfRange(Double_t,ReadArrayFunc); \
510 case TStreamerInfo::kDouble32: ConvCBasicPointerToOutOfRange(Double_t,ReadArrayFunc); \
511 case TStreamerInfo::kUChar: ConvCBasicPointerToOutOfRange(UChar_t,ReadArrayFunc); \
512 case TStreamerInfo::kUShort: ConvCBasicPointerToOutOfRange(UShort_t,ReadArrayFunc); \
513 case TStreamerInfo::kUInt: ConvCBasicPointerToOutOfRange(UInt_t,ReadArrayFunc); \
514 case TStreamerInfo::kULong: ConvCBasicPointerToOutOfRange(ULong_t,ReadArrayFunc); \
515 case TStreamerInfo::kULong64: ConvCBasicPointerToOutOfRange(ULong64_t,ReadArrayFunc); \
516 } \
517 } \
518 readbuf = 0; \
519 } break; \
520 }
521
522////////////////////////////////////////////////////////////////////////////////
523/// Handle Artificial StreamerElement
524
525template <class T>
527 TStreamerElement *aElement, Int_t narr,
528 Int_t eoffset)
529{
530 TStreamerArtificial *artElement = (TStreamerArtificial*)aElement;
532
533 if (rawfunc) {
534 for(Int_t k=0; k<narr; ++k) {
535 rawfunc( arr[k], b ); // Intentionally pass the object, so that the member can be set from other members.
536 }
537 return 0;
538 }
539
540 ROOT::TSchemaRule::ReadFuncPtr_t readfunc = artElement->GetReadFunc();
541 // Process the result
542 if (readfunc) {
543 TVirtualObject obj(0);
544 TVirtualArray *objarr = ((TBufferFile&)b).PeekDataCache();
545 if (objarr) {
546 obj.fClass = objarr->fClass;
547
548 for(Int_t k=0; k<narr; ++k) {
549 obj.fObject = objarr->GetObjectAt(k);
550 readfunc(arr[k]+eoffset, &obj);
551 }
552 obj.fObject = 0; // Prevent auto deletion
553 } else {
554 for(Int_t k=0; k<narr; ++k) {
555 readfunc(arr[k]+eoffset, &obj);
556 }
557 }
558 return 0;
559 }
560
561 return 0;
562}
563
564////////////////////////////////////////////////////////////////////////////////
565/// Convert elements of a TClonesArray
566
567template <class T>
568Int_t TStreamerInfo::ReadBufferConv(TBuffer &b, const T &arr, const TCompInfo *compinfo, Int_t kase,
569 TStreamerElement *aElement, Int_t narr,
570 Int_t eoffset)
571{
572 Int_t ioffset = eoffset+compinfo->fOffset;
573
574 switch (kase) {
575
576 // convert basic types
583 } else {
584 ConvCBasicType(Long_t,b >> u);
585 }
588 case TStreamerInfo::kConv + TStreamerInfo::kFloat16: ConvCBasicType(Float_t,b.ReadFloat16(&u,aElement));
595#if defined(_MSC_VER) && (_MSC_VER <= 1200)
597#else
599#endif
600 } else {
602 }
603#if defined(_MSC_VER) && (_MSC_VER <= 1200)
605#else
607#endif
609 DOLOOP {
610 UInt_t u;
611 b >> u;
612 u |= kNotDeleted; // by definition de-serialized object are not yet deleted.
613 if ((u & kIsReferenced) != 0) {
614 UShort_t pidf;
615 b >> pidf;
616 pidf += b.GetPidOffset();
617 TProcessID *pid = b.ReadProcessID(pidf);
618 if (pid!=0) {
619 TObject *obj = (TObject*)(arr[k]+eoffset);
620 UInt_t gpid = pid->GetUniqueID();
621 UInt_t uid;
622 if (gpid>=0xff) {
623 uid = obj->GetUniqueID() | 0xff000000;
624 } else {
625 uid = ( obj->GetUniqueID() & 0xffffff) + (gpid<<24);
626 }
627 obj->SetUniqueID(uid);
628 pid->PutObjectWithID(obj);
629 }
630 }
631 switch(compinfo->fNewType) {
632 case TStreamerInfo::kBool: {Bool_t *x=(Bool_t*)(arr[k]+ioffset); *x = (Bool_t)u; break;}
633 case TStreamerInfo::kChar: {Char_t *x=(Char_t*)(arr[k]+ioffset); *x = (Char_t)u; break;}
634 case TStreamerInfo::kShort: {Short_t *x=(Short_t*)(arr[k]+ioffset); *x = (Short_t)u; break;}
635 case TStreamerInfo::kInt: {Int_t *x=(Int_t*)(arr[k]+ioffset); *x = (Int_t)u; break;}
636 case TStreamerInfo::kLong: {Long_t *x=(Long_t*)(arr[k]+ioffset); *x = (Long_t)u; break;}
637 case TStreamerInfo::kLong64: {Long64_t *x=(Long64_t*)(arr[k]+ioffset); *x = (Long64_t)u; break;}
638 case TStreamerInfo::kFloat: {Float_t *x=(Float_t*)(arr[k]+ioffset); *x = (Float_t)u; break;}
639 case TStreamerInfo::kFloat16: {Float_t *x=(Float_t*)(arr[k]+ioffset); *x = (Float_t)u; break;}
640 case TStreamerInfo::kDouble: {Double_t *x=(Double_t*)(arr[k]+ioffset); *x = (Double_t)u; break;}
641 case TStreamerInfo::kDouble32:{Double_t *x=(Double_t*)(arr[k]+ioffset); *x = (Double_t)u; break;}
642 case TStreamerInfo::kUChar: {UChar_t *x=(UChar_t*)(arr[k]+ioffset); *x = (UChar_t)u; break;}
643 case TStreamerInfo::kUShort: {UShort_t *x=(UShort_t*)(arr[k]+ioffset); *x = (UShort_t)u; break;}
644 case TStreamerInfo::kUInt: {UInt_t *x=(UInt_t*)(arr[k]+ioffset); *x = (UInt_t)u; break;}
645 case TStreamerInfo::kULong: {ULong_t *x=(ULong_t*)(arr[k]+ioffset); *x = (ULong_t)u; break;}
646 case TStreamerInfo::kULong64: {ULong64_t*x=(ULong64_t*)(arr[k]+ioffset);*x = (ULong64_t)u;break;}
647 }
648 } break;
649 }
650
651 // convert array of basic types array[8]
658 ConvCBasicArray(Long64_t,ReadFastArray);
659 } else {
660 ConvCBasicArray(Long_t,ReadFastArray);
661 }
672#if defined(_MSC_VER) && (_MSC_VER <= 1200)
673 ConvCBasicArray(Long64_t,ReadFastArray)
674#else
675 ConvCBasicArray(ULong64_t,ReadFastArray)
676#endif
677 } else {
678 ConvCBasicArray(ULong_t,ReadFastArray);
679 }
680#if defined(_MSC_VER) && (_MSC_VER <= 1200)
682#else
684#endif
685
686 // convert pointer to an array of basic types array[n]
693 ConvCBasicPointer(Long64_t,ReadFastArray);
694 } else {
695 ConvCBasicPointer(Long_t,ReadFastArray);
696 }
707#if defined(_MSC_VER) && (_MSC_VER <= 1200)
708 ConvCBasicPointer(Long64_t,ReadFastArray)
709#else
710 ConvCBasicPointer(ULong64_t,ReadFastArray)
711#endif
712 } else {
713 ConvCBasicPointer(ULong_t,ReadFastArray);
714 }
715#if defined(_MSC_VER) && (_MSC_VER <= 1200)
717#else
719#endif
720
721 default:
722 // Warning("ReadBufferConv","The element type %d is not supported yet",compinfo->fType);
723 return -1;
724
725 }
726
727 return 0;
728}
729
730// Helper function for TStreamerInfo::ReadBuffer
731namespace {
732 template <class T> Bool_t R__TestUseCache(TStreamerElement *element)
733 {
734 return element->TestBit(TStreamerElement::kCache);
735 }
736
737 template <> Bool_t R__TestUseCache<TVirtualArray>(TStreamerElement*)
738 {
739 // We are already using the cache, no need to recurse one more time.
740 return kFALSE;
741 }
742}
743
744////////////////////////////////////////////////////////////////////////////////
745/// Deserialize information from buffer b into object at pointer
746/// if (arrayMode & 1) ptr is a pointer to array of pointers to the objects
747/// otherwise it is a pointer to a pointer to a single object.
748/// This also means that T is of a type such that arr[i] is a pointer to an
749/// object. Currently the only anticipated instantiation are for T==char**
750/// and T==TVirtualCollectionProxy
751
752template <class T>
754 TCompInfo *const*const compinfo, Int_t first, Int_t last,
755 Int_t narr, Int_t eoffset, Int_t arrayMode)
756{
757 TStreamerInfo *thisVar = this;
758 Bool_t needIncrement = !( arrayMode & 2 );
759 arrayMode = arrayMode & (~2);
760
761 if (needIncrement) b.IncrementLevel(thisVar);
762
763 //loop on all active members
764
765 // In order to speed up the case where the object being written is
766 // not in a collection (i.e. arrayMode is false), we actually
767 // duplicate the code for the elementary types using this typeOffset.
768 static const int kHaveLoop = 1024;
769 const Int_t typeOffset = arrayMode ? kHaveLoop : 0;
770
771 TClass *cle = 0;
772 TClass *newCle = 0;
773 TMemberStreamer *pstreamer=0;
774 Int_t isPreAlloc = 0;
775 for (Int_t i=first;i<last;i++) {
776 TStreamerElement * aElement = (TStreamerElement*)compinfo[i]->fElem;
777 CurrentElement() = aElement;
778
779 if (needIncrement) b.SetStreamerElementNumber(aElement,compinfo[i]->fType);
780
781 if (aElement->TestBit(TStreamerElement::kWrite)) continue;
782
783 if (R__TestUseCache<T>(aElement)) {
784 Int_t bufpos = b.Length();
785 if (((TBufferFile&)b).PeekDataCache()==0) {
786 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",thisVar->GetName(),aElement->GetName());
787 thisVar->ReadBufferSkip(b,arr,compinfo[i],compinfo[i]->fType+TStreamerInfo::kSkip,aElement,narr,eoffset);
788 } else {
789 if (gDebug > 1) {
790 printf("ReadBuffer, class:%s, name=%s, fType[%d]=%d,"
791 " %s, bufpos=%d, arr=%p, eoffset=%d, Redirect=%p\n",
792 fClass->GetName(),aElement->GetName(),i,compinfo[i]->fType,
793 aElement->ClassName(),b.Length(),arr[0], eoffset,((TBufferFile&)b).PeekDataCache()->GetObjectAt(0));
794 }
795 thisVar->ReadBuffer(b,*((TBufferFile&)b).PeekDataCache(),compinfo,i,i+1,narr,eoffset, arrayMode);
796 }
797 if (aElement->TestBit(TStreamerElement::kRepeat)) { b.SetBufferOffset(bufpos); }
798 continue;
799 }
800 const Int_t ioffset = compinfo[i]->fOffset+eoffset;
801
802 if (gDebug > 1) {
803 printf("ReadBuffer, class:%s, name=%s, fType[%d]=%d,"
804 " %s, bufpos=%d, arr=%p, offset=%d\n",
805 fClass->GetName(),aElement->GetName(),i,compinfo[i]->fType,
806 aElement->ClassName(),b.Length(),arr[0], ioffset);
807 }
808
809 Int_t kase = compinfo[i]->fType;
810
811 switch (kase + typeOffset) {
812
813 // read basic types
817 case TStreamerInfo::kInt: ReadBasicType(Int_t); continue;
828 Float_t *x=(Float_t*)(arr[0]+ioffset);
829 b.ReadFloat16(x,aElement);
830 continue;
831 }
833 Double_t *x=(Double_t*)(arr[0]+ioffset);
834 b.ReadDouble32(x,aElement);
835 continue;
836 }
837
838 case TStreamerInfo::kBool + kHaveLoop: ReadBasicTypeLoop(Bool_t); continue;
839 case TStreamerInfo::kChar + kHaveLoop: ReadBasicTypeLoop(Char_t); continue;
840 case TStreamerInfo::kShort + kHaveLoop: ReadBasicTypeLoop(Short_t); continue;
841 case TStreamerInfo::kInt + kHaveLoop: ReadBasicTypeLoop(Int_t); continue;
842 case TStreamerInfo::kLong + kHaveLoop: ReadBasicTypeLoop(Long_t); continue;
843 case TStreamerInfo::kLong64 + kHaveLoop: ReadBasicTypeLoop(Long64_t); continue;
844 case TStreamerInfo::kFloat + kHaveLoop: ReadBasicTypeLoop(Float_t); continue;
845 case TStreamerInfo::kDouble + kHaveLoop: ReadBasicTypeLoop(Double_t); continue;
846 case TStreamerInfo::kUChar + kHaveLoop: ReadBasicTypeLoop(UChar_t); continue;
847 case TStreamerInfo::kUShort + kHaveLoop: ReadBasicTypeLoop(UShort_t); continue;
848 case TStreamerInfo::kUInt + kHaveLoop: ReadBasicTypeLoop(UInt_t); continue;
849 case TStreamerInfo::kULong + kHaveLoop: ReadBasicTypeLoop(ULong_t); continue;
850 case TStreamerInfo::kULong64+ kHaveLoop: ReadBasicTypeLoop(ULong64_t); continue;
851 case TStreamerInfo::kFloat16 + kHaveLoop: {
852 for(Int_t k=0; k<narr; ++k) {
853 Float_t *x=(Float_t*)(arr[k]+ioffset);
854 b.ReadFloat16(x,aElement);
855 }
856 continue;
857 }
858 case TStreamerInfo::kDouble32 + kHaveLoop: {
859 for(Int_t k=0; k<narr; ++k) {
860 Double_t *x=(Double_t*)(arr[k]+ioffset);
861 b.ReadDouble32(x,aElement);
862 }
863 continue;
864 }
865
866 // read array of basic types like array[8]
881 b.ReadFastArrayFloat16((Float_t*)(arr[0]+ioffset),compinfo[i]->fLength,aElement);
882 continue;
883 }
885 b.ReadFastArrayDouble32((Double_t*)(arr[0]+ioffset),compinfo[i]->fLength,aElement);
886 continue;
887 }
888
903 for(Int_t k=0; k<narr; ++k) {
904 b.ReadFastArrayFloat16((Float_t*)(arr[k]+ioffset),compinfo[i]->fLength,aElement);
905 }
906 continue;
907 }
909 for(Int_t k=0; k<narr; ++k) {
910 b.ReadFastArrayDouble32((Double_t*)(arr[k]+ioffset),compinfo[i]->fLength,aElement);
911 }
912 continue;
913 }
914
915 // read pointer to an array of basic types array[n]
930 Char_t isArray;
931 b >> isArray;
932 const int imethod = compinfo[i]->fMethod+eoffset;
933 Int_t *l = (Int_t*)(arr[0]+imethod);
934 Float_t **f = (Float_t**)(arr[0]+ioffset);
935 int j;
936 for(j=0;j<compinfo[i]->fLength;j++) {
937 delete [] f[j];
938 f[j] = 0; if (*l <=0) continue;
939 f[j] = new Float_t[*l];
940 b.ReadFastArrayFloat16(f[j],*l,aElement);
941 }
942 continue;
943 }
945 Char_t isArray;
946 b >> isArray;
947 const int imethod = compinfo[i]->fMethod+eoffset;
948 Int_t *l = (Int_t*)(arr[0]+imethod);
949 Double_t **f = (Double_t**)(arr[0]+ioffset);
950 int j;
951 for(j=0;j<compinfo[i]->fLength;j++) {
952 delete [] f[j];
953 f[j] = 0; if (*l <=0) continue;
954 f[j] = new Double_t[*l];
955 b.ReadFastArrayDouble32(f[j],*l,aElement);
956 }
957 continue;
958 }
959
974 const int imethod = compinfo[i]->fMethod+eoffset;
975 for(Int_t k=0; k<narr; ++k) {
976 Char_t isArray;
977 b >> isArray;
978 Int_t *l = (Int_t*)(arr[k]+imethod);
979 Float_t **f = (Float_t**)(arr[k]+ioffset);
980 int j;
981 for(j=0;j<compinfo[i]->fLength;j++) {
982 delete [] f[j];
983 f[j] = 0; if (*l <=0) continue;
984 f[j] = new Float_t[*l];
985 b.ReadFastArrayFloat16(f[j],*l,aElement);
986 }
987 }
988 continue;
989 }
991 const int imethod = compinfo[i]->fMethod+eoffset;
992 for(Int_t k=0; k<narr; ++k) {
993 Char_t isArray;
994 b >> isArray;
995 Int_t *l = (Int_t*)(arr[k]+imethod);
996 Double_t **f = (Double_t**)(arr[k]+ioffset);
997 int j;
998 for(j=0;j<compinfo[i]->fLength;j++) {
999 delete [] f[j];
1000 f[j] = 0; if (*l <=0) continue;
1001 f[j] = new Double_t[*l];
1002 b.ReadFastArrayDouble32(f[j],*l,aElement);
1003 }
1004 }
1005 continue;
1006 }
1007 }
1008
1009 switch (kase) {
1010
1011 // char*
1013 DOLOOP {
1014 char **f = (char**)(arr[k]+ioffset);
1015 b.ReadCharStar(*f);
1016 }
1017 }
1018 continue;
1019
1020 // special case for TObject::fBits in case of a referenced object
1021 case TStreamerInfo::kBits: {
1022 DOLOOP {
1023 UInt_t *x=(UInt_t*)(arr[k]+ioffset);
1024 const UInt_t isonheap = *x & TObject::kIsOnHeap; // Record how this instance was actually allocated.
1025 b >> *x;
1026 *x |= isonheap | TObject::kNotDeleted; // by definition de-serialized object are not yet deleted.
1027 if ((*x & kIsReferenced) != 0) {
1028 UShort_t pidf;
1029 b >> pidf;
1030 pidf += b.GetPidOffset();
1031 TProcessID *pid = b.ReadProcessID(pidf);
1032 if (pid!=0) {
1033 TObject *obj = (TObject*)(arr[k]+eoffset);
1034 UInt_t gpid = pid->GetUniqueID();
1035 UInt_t uid;
1036 if (gpid>=0xff) {
1037 uid = obj->GetUniqueID() | 0xff000000;
1038 } else {
1039 uid = ( obj->GetUniqueID() & 0xffffff) + (gpid<<24);
1040 }
1041 obj->SetUniqueID(uid);
1042 pid->PutObjectWithID(obj);
1043 }
1044 }
1045 }
1046 }
1047 continue;
1048
1049 // array counter //[n]
1051 DOLOOP {
1052 Int_t *x=(Int_t*)(arr[k]+ioffset);
1053 b >> *x;
1054 }
1055 }
1056 continue;
1057
1058
1059 // Special case for TString, TObject, TNamed
1060 case TStreamerInfo::kTString: { DOLOOP { ((TString*)(arr[k]+ioffset))->Streamer(b); } } continue;
1061 case TStreamerInfo::kTObject: { DOLOOP { ((TObject*)(arr[k]+ioffset))->TObject::Streamer(b);} } continue;
1062 case TStreamerInfo::kTNamed: { DOLOOP { ((TNamed*) (arr[k]+ioffset))->TNamed::Streamer(b) ;} } continue;
1063
1064 }
1065
1066 SWIT:
1067 isPreAlloc= 0;
1068 cle = compinfo[i]->fClass;
1069 newCle = compinfo[i]->fNewClass;
1070 pstreamer = compinfo[i]->fStreamer;
1071
1072 switch (kase) {
1073
1074 case TStreamerInfo::kAnyp: // Class* not derived from TObject with comment field //->
1076 case TStreamerInfo::kObjectp: // Class* derived from TObject with comment field //->
1078 isPreAlloc = 1;
1079 // Intentional fallthrough now that isPreAlloc is set.
1080 case TStreamerInfo::kObjectP: // Class* derived from TObject with no comment field NOTE: Re-added by Phil
1082 case TStreamerInfo::kAnyP: // Class* not derived from TObject with no comment field NOTE:: Re-added by Phil
1084 DOLOOP {
1085 b.ReadFastArray((void**)(arr[k]+ioffset),cle,compinfo[i]->fLength,isPreAlloc,pstreamer);
1086 }
1087 }
1088 continue;
1089
1090// case TStreamerInfo::kSTLvarp: // Variable size array of STL containers.
1091// {
1092// TMemberStreamer *pstreamer = compinfo[i]->fStreamer;
1093// TClass *cl = compinfo[i]->fClass;
1094// ROOT::NewArrFunc_t arraynew = cl->GetNewArray();
1095// ROOT::DelArrFunc_t arraydel = cl->GetDeleteArray();
1096// UInt_t start,count;
1097// // Version_t v =
1098// b.ReadVersion(&start, &count, cle);
1099// if (pstreamer == 0) {
1100// Int_t size = cl->Size();
1101// Int_t imethod = compinfo[i]->fMethod+eoffset;
1102// DOLOOP {
1103// char **contp = (char**)(arr[k]+ioffset);
1104// const Int_t *counter = (Int_t*)(arr[k]+imethod);
1105// const Int_t sublen = (*counter);
1106
1107// for(int j=0;j<compinfo[i]->fLength;++j) {
1108// if (arraydel) arraydel(contp[j]);
1109// contp[j] = 0;
1110// if (sublen<=0) continue;
1111// if (arraynew) {
1112// contp[j] = (char*)arraynew(sublen, 0);
1113// char *cont = contp[j];
1114// for(int k=0;k<sublen;++k) {
1115// cl->Streamer( cont, b );
1116// cont += size;
1117// }
1118// } else {
1119// // Can't create an array of object
1120// Error("ReadBuffer","The element %s::%s type %d (%s) can be read because of the class does not have access to new %s[..]\n",
1121// GetName(),aElement->GetFullName(),kase,aElement->GetTypeName(),GetName());
1122// void *cont = cl->New();
1123// for(int k=0;k<sublen;++k) {
1124// cl->Streamer( cont, b );
1125// }
1126// }
1127// }
1128// }
1129// } else {
1130// DOLOOP{(*pstreamer)(b,arr[k]+ioffset,compinfo[i]->fLength);}
1131// }
1132// b.CheckByteCount(start,count,aElement->GetFullName());
1133// }
1134// continue;
1135
1136 case TStreamerInfo::kSTLp: // Pointer to Container with no virtual table (stl) and no comment
1137 case TStreamerInfo::kSTLp + TStreamerInfo::kOffsetL: // array of pointers to Container with no virtual table (stl) and no comment
1138 {
1139 UInt_t start,count;
1140 Version_t vers = b.ReadVersion(&start, &count, cle);
1141
1142 if ( vers & TBufferFile::kStreamedMemberWise ) {
1143 // Collection was saved member-wise
1144
1146
1147 TClass *newClass = aElement->GetNewClass();
1148 TClass *oldClass = aElement->GetClassPointer();
1149 if( vers < 9 && newClass && newClass!=oldClass ) {
1150 Error( "ReadBuffer", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
1151 vers, b.GetParent() ? b.GetParent()->GetName() : "memory/socket", oldClass->GetName(), newClass->GetName() );
1152 continue;
1153 }
1154
1155 Version_t vClVersion = 0; // For vers less than 9, we have to use the current version.
1156 if( vers >= 9 ) {
1157 vClVersion = b.ReadVersionForMemberWise( cle->GetCollectionProxy()->GetValueClass() );
1158 }
1159
1160 TVirtualCollectionProxy *newProxy = (newClass ? newClass->GetCollectionProxy() : 0);
1161 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
1162 TStreamerInfo *subinfo = 0;
1163
1164 if( newProxy ) {
1165 // coverity[dereference] oldProxy->GetValueClass() can not be null since this was streamed memberwise.
1166 subinfo = (TStreamerInfo*)newProxy->GetValueClass()->GetConversionStreamerInfo( oldProxy->GetValueClass(), vClVersion );
1167 } else {
1168 subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( vClVersion );
1169 newProxy = oldProxy;
1170 }
1171 if (subinfo) {
1172 DOLOOP {
1173 void* env;
1174 void **contp = (void**)(arr[k]+ioffset);
1175 int j;
1176 for(j=0;j<compinfo[i]->fLength;j++) {
1177 void *cont = contp[j];
1178 if (cont==0) {
1179 contp[j] = cle->New();
1180 cont = contp[j];
1181 }
1182 TVirtualCollectionProxy::TPushPop helper( newProxy, cont );
1183 Int_t nobjects;
1184 b >> nobjects;
1185 env = newProxy->Allocate(nobjects,true);
1186 if (!nobjects && (vers>=7)) {
1187 // Do nothing but in version 6 of TStreamerInfo and below,
1188 // we were calling ReadBuffer for empty collection.
1189 } else {
1190 TStreamerInfoActions::TActionSequence *actions = nullptr;
1191 if (newProxy != oldProxy) {
1192 actions = newProxy->GetConversionReadMemberWiseActions( oldProxy->GetValueClass(), vClVersion );
1193 } else {
1194 actions = oldProxy->GetReadMemberWiseActions( vClVersion );
1195 }
1198 void *begin = &(startbuf[0]);
1199 void *end = &(endbuf[0]);
1200 newProxy->GetFunctionCreateIterators(/* read = */ kTRUE)(env, &begin, &end, newProxy);
1201 // We can not get here with a split vector of pointer, so we can indeed assume
1202 // that actions->fConfiguration != null.
1203 b.ApplySequence(*actions, begin, end);
1204 if (begin != &(startbuf[0])) {
1205 // assert(end != endbuf);
1206 newProxy->GetFunctionDeleteTwoIterators()(begin,end);
1207 }
1208 }
1209 newProxy->Commit(env);
1210 }
1211 }
1212 }
1213 b.CheckByteCount(start,count,aElement->GetFullName());
1214 continue;
1215 }
1216 if (pstreamer == 0) {
1217 DOLOOP {
1218 void **contp = (void**)(arr[k]+ioffset);
1219 int j;
1220 for(j=0;j<compinfo[i]->fLength;j++) {
1221 void *cont = contp[j];
1222 if (cont==0) {
1223 // int R__n;
1224 // b >> R__n;
1225 // b.SetOffset(b.GetOffset()-4); // rewind to the start of the int
1226 // if (R__n) continue;
1227 contp[j] = cle->New();
1228 cont = contp[j];
1229 }
1230 cle->Streamer( cont, b );
1231 }
1232 }
1233 } else {
1234 DOLOOP {(*pstreamer)(b,arr[k]+ioffset,compinfo[i]->fLength);}
1235 }
1236 b.CheckByteCount(start,count,aElement->GetFullName());
1237 }
1238 continue;
1239
1240 case TStreamerInfo::kSTL: // Container with no virtual table (stl) and no comment
1241 case TStreamerInfo::kSTL + TStreamerInfo::kOffsetL: // array of Container with no virtual table (stl) and no comment
1242 {
1243 UInt_t start, count;
1244 Version_t vers = b.ReadVersion(&start, &count, cle);
1245
1246 if ( vers & TBufferFile::kStreamedMemberWise ) {
1247 // Collection was saved member-wise
1249
1250 TClass *newClass = aElement->GetNewClass();
1251 TClass *oldClass = aElement->GetClassPointer();
1252
1253 if( vers < 8 && newClass && newClass!=oldClass ) {
1254 Error( "ReadBuffer", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
1255 vers, b.GetParent() ? b.GetParent()->GetName() : "memory/socket", oldClass->GetName(), newClass->GetName() );
1256 continue;
1257 }
1258 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
1259 TClass *valueClass = oldProxy ? oldProxy->GetValueClass() : 0;
1260 Version_t vClVersion = 0; // For vers less than 8, we have to use the current version.
1261 if( vers >= 8 ) {
1262 vClVersion = b.ReadVersionForMemberWise( valueClass );
1263 }
1264
1265 if (valueClass == 0) {
1266 // MemberWise streaming applies to only collection of classes, and hence
1267 // valueClass can only be null if we are reading without the original library
1268 // and the collection is always empty,
1269 // So let's skip the rest (which requires the StreamerInfo of the valueClass ... which we do not have)
1270
1271 b.SetBufferOffset(start+count+sizeof(UInt_t));
1272 continue;
1273 }
1274
1275 TVirtualCollectionProxy *newProxy = (newClass ? newClass->GetCollectionProxy() : 0);
1276 TStreamerInfo *subinfo = 0;
1277
1278 if( newProxy ) {
1279 // coverity[dereference] oldProxy->GetValueClass() can not be null since this was streamed memberwise.
1280 subinfo = (TStreamerInfo*)newProxy->GetValueClass()->GetConversionStreamerInfo( oldProxy->GetValueClass(), vClVersion );
1281 } else {
1282 subinfo = (TStreamerInfo*)valueClass->GetStreamerInfo( vClVersion );
1283 newProxy = oldProxy;
1284 }
1285 if (subinfo) {
1286 DOLOOP {
1287 int objectSize = cle->Size();
1288 char *obj = arr[k]+ioffset;
1289 char *end = obj + compinfo[i]->fLength*objectSize;
1290
1291 for(; obj<end; obj+=objectSize) {
1292 TVirtualCollectionProxy::TPushPop helper( newProxy, obj );
1293 Int_t nobjects;
1294 b >> nobjects;
1295 void* env = newProxy->Allocate(nobjects,true);
1296 if (!nobjects && (vers>=7)) {
1297 // Do nothing but in version 6 of TStreamerInfo and below,
1298 // we were calling ReadBuffer for empty collection.
1299 } else {
1300 TStreamerInfoActions::TActionSequence *actions = nullptr;
1301 if (newProxy != oldProxy) {
1302 actions = newProxy->GetConversionReadMemberWiseActions( oldProxy->GetValueClass(), vClVersion );
1303 } else {
1304 actions = oldProxy->GetReadMemberWiseActions( vClVersion );
1305 }
1306
1309 void *begin_iter = &(startbuf[0]);
1310 void *end_iter = &(endbuf[0]);
1311 newProxy->GetFunctionCreateIterators(/* read = */ kTRUE)(env, &begin_iter, &end_iter, newProxy);
1312 // We can not get here with a split vector of pointer, so we can indeed assume
1313 // that actions->fConfiguration != null.
1314 b.ApplySequence(*actions, begin_iter, end_iter);
1315 if (begin_iter != &(startbuf[0])) {
1316 // assert(end != endbuf);
1317 newProxy->GetFunctionDeleteTwoIterators()(begin_iter,end_iter);
1318 }
1319 }
1320 newProxy->Commit(env);
1321 }
1322 }
1323 }
1324 b.CheckByteCount(start,count,aElement->GetTypeName());
1325 continue;
1326 }
1327 if (fOldVersion<3){ // case of old TStreamerInfo
1328 // Backward compatibility. Some TStreamerElement's where without
1329 // Streamer but were not removed from element list
1330 if (aElement->IsBase() && aElement->IsA()!=TStreamerBase::Class()) {
1331 b.SetBufferOffset(start); //there is no byte count
1332 } else if (vers==0) {
1333 b.SetBufferOffset(start); //there is no byte count
1334 }
1335 }
1336 if (pstreamer == 0) {
1337 if( !newCle ) {
1338 newCle = cle;
1339 cle = 0;
1340 }
1341 DOLOOP {
1342 b.ReadFastArray((void*)(arr[k]+ioffset),newCle,compinfo[i]->fLength,(TMemberStreamer*)0, cle );
1343 }
1344 } else {
1345 DOLOOP {(*pstreamer)(b,arr[k]+ioffset,compinfo[i]->fLength);}
1346 }
1347 b.CheckByteCount(start,count,aElement->GetTypeName());
1348 }
1349 continue;
1350
1351 case TStreamerInfo::kObject: // Class derived from TObject
1352 if (cle->IsStartingWithTObject() && cle->GetState() > TClass::kEmulated) {
1353 DOLOOP {((TObject*)(arr[k]+ioffset))->Streamer(b);}
1354 continue; // intentionally inside the if statement.
1355 // if the class does not start with its TObject part (or does
1356 // not have one), we use the generic case.
1357 }
1358 case TStreamerInfo::kAny: // Class not derived from TObject
1359 if (pstreamer) {
1360 DOLOOP {(*pstreamer)(b,arr[k]+ioffset,0);}
1361 } else {
1362 if( newCle )
1363 DOLOOP { newCle->Streamer( arr[k]+ioffset, b, cle ); }
1364 else
1365 DOLOOP { cle->Streamer(arr[k]+ioffset,b);}
1366 }
1367 continue;
1368
1370 TFile *file = (TFile*)b.GetParent();
1371 if (file && file->GetVersion() < 30208) {
1372 // For older ROOT file we use a totally different case to treat
1373 // this situation, so we change 'kase' and restart.
1375 goto SWIT;
1376 }
1377 // there is intentionally no break/continue statement here.
1378 // For newer ROOT file, we always use the generic case for kOffsetL(s)
1379 }
1380
1382 DOLOOP {
1383 b.ReadFastArray((void*)(arr[k]+ioffset),cle,compinfo[i]->fLength,pstreamer);
1384 }
1385 continue;
1386 }
1387
1388 // Base Class
1390 if (!(arrayMode&1)) {
1391 if(pstreamer) {kase = TStreamerInfo::kStreamer; goto SWIT;}
1392 DOLOOP { ((TStreamerBase*)aElement)->ReadBuffer(b,arr[k]);}
1393 } else {
1394 // FIXME: Rather than relying on the StreamerElement to
1395 // contain the base class version information we should
1396 // embed it in the bytestream even in the member-wise case.
1397 // For now rely, on the StreamerElement:
1398 TStreamerInfo *binfo = ((TStreamerInfo*)((TStreamerBase*)aElement)->GetBaseStreamerInfo());
1399 binfo->ReadBuffer(b,arr,binfo->fCompFull,0,binfo->fNfulldata,narr,ioffset,arrayMode);
1400 }
1401 continue;
1402
1406 {
1407 // Backward compatibility. Some TStreamerElement's where without
1408 // Streamer but were not removed from element list
1409 UInt_t start,count;
1410 Version_t v = b.ReadVersion(&start, &count, cle);
1411 if (fOldVersion<3){ // case of old TStreamerInfo
1412 if (count<= 0 || v != fOldVersion) {
1413 b.SetBufferOffset(start);
1414 continue;
1415 }
1416 }
1417 DOLOOP {
1418 b.ReadFastArray((void*)(arr[k]+ioffset),cle,compinfo[i]->fLength,pstreamer);
1419 }
1420 b.CheckByteCount(start,count,aElement->GetFullName());
1421 continue;
1422 }
1423
1424
1426 // Backward compatibility. Some TStreamerElement's where without
1427 // Streamer but were not removed from element list
1428 UInt_t start,count;
1429 Version_t v = b.ReadVersion(&start, &count, this->IsA());
1430 if (fOldVersion<3){ // case of old TStreamerInfo
1431 if (aElement->IsBase() && aElement->IsA()!=TStreamerBase::Class()) {
1432 b.SetBufferOffset(start); //it was no byte count
1433 } else if (kase == TStreamerInfo::kSTL || kase == TStreamerInfo::kSTL+TStreamerInfo::kOffsetL ||
1434 count<= 0 || v != fOldVersion) {
1435 b.SetBufferOffset(start);
1436 continue;
1437 }
1438 }
1439 if (pstreamer == 0) {
1440 Error("ReadBuffer","Streamer for %s is null\n",aElement->GetName());
1441 if (gDebug > 0) {
1442 aElement->ls(); continue;
1443 }
1444 } else {
1445 DOLOOP {(*pstreamer)(b,arr[k]+ioffset,compinfo[i]->fLength);}
1446 }
1447 b.CheckByteCount(start,count,aElement->GetFullName());
1448 }
1449 continue;
1450
1452 // -- A pointer to a varying-length array of objects.
1453 // MyClass* ary; //[n]
1454 // -- Or a pointer to a varying-length array of pointers to objects.
1455 // MyClass** ary; //[n]
1457 // -- An array of pointers to a varying-length array of objects.
1458 // MyClass* ary[d]; //[n]
1459 // -- Or an array of pointers to a varying-length array of pointers to objects.
1460 // MyClass** ary[d]; //[n]
1461 {
1462 // Get the class of the data member.
1463 TClass* cl = compinfo[i]->fClass;
1464 // Which are we, an array of objects or an array of pointers to objects?
1465 Bool_t isPtrPtr = (strstr(aElement->GetTypeName(), "**") != 0);
1466 // Check for a private streamer.
1467 if (pstreamer) {
1468 // -- We have a private streamer.
1469 // Read the class version and byte count from the buffer.
1470 UInt_t start = 0;
1471 UInt_t count = 0;
1472 b.ReadVersion(&start, &count, cl);
1473 // Loop over the entries in the clones array or the STL container.
1474 for (Int_t k = 0; k < narr; ++k) {
1475 Int_t* counter = (Int_t*) (arr[k] /*entry pointer*/ + eoffset /*entry offset*/ + compinfo[i]->fMethod /*counter offset*/);
1476 // And call the private streamer, passing it the buffer, the object, and the counter.
1477 (*pstreamer)(b, arr[k] /*entry pointer*/ + ioffset /*object offset*/, *counter);
1478 }
1479 b.CheckByteCount(start, count, aElement->GetFullName());
1480 // We are done, next streamer element.
1481 continue;
1482 }
1483 // At this point we do *not* have a private streamer.
1484 // Get the version of the file we are reading from.
1485 TFile* file = (TFile*) b.GetParent();
1486 // By default assume the file version is the newest.
1487 Int_t fileVersion = kMaxInt;
1488 if (file) {
1489 fileVersion = file->GetVersion();
1490 }
1491 // Read the class version and byte count from the buffer.
1492 UInt_t start = 0;
1493 UInt_t count = 0;
1494 b.ReadVersion(&start, &count, cl);
1495 if (fileVersion > 51508) {
1496 // -- Newer versions allow polymorphic pointers.
1497 // Loop over the entries in the clones array or the STL container.
1498 for (Int_t k = 0; k < narr; ++k) {
1499 // Get the counter for the varying length array.
1500 Int_t vlen = *((Int_t*) (arr[k] /*entry pointer*/ + eoffset /*entry offset*/ + compinfo[i]->fMethod /*counter offset*/));
1501 //Int_t realLen;
1502 //b >> realLen;
1503 //if (realLen != vlen) {
1504 // fprintf(stderr, "read vlen: %d realLen: %s\n", vlen, realLen);
1505 //}
1506 // Get a pointer to the array of pointers.
1507 char** pp = (char**) (arr[k] /*entry pointer*/ + ioffset /*object offset*/);
1508 if (!pp) {
1509 continue;
1510 }
1511 // Loop over each element of the array of pointers to varying-length arrays.
1512 for (Int_t ndx = 0; ndx < compinfo[i]->fLength; ++ndx) {
1513 //if (!pp[ndx]) {
1514 // -- We do not have a pointer to a varying-length array.
1515 //Error("ReadBuffer", "The pointer to element %s::%s type %d (%s) is null\n", thisVar->GetName(), aElement->GetFullName(), compinfo[i]->fType, aElement->GetTypeName());
1516 //continue;
1517 //}
1518 // Delete any memory at pp[ndx].
1519 if (!isPtrPtr) {
1520 cl->DeleteArray(pp[ndx]);
1521 pp[ndx] = 0;
1522 } else {
1523 // Using vlen is wrong here because it has already
1524 // been overwritten with the value needed to read
1525 // the current record. Fixing this will require
1526 // doing a pass over the object at the beginning
1527 // of the I/O and releasing all the buffer memory
1528 // for varying length arrays before we overwrite
1529 // the counter values.
1530 //
1531 // For now we will just leak memory, just as we
1532 // have always done in the past. Fix this.
1533 //
1534 //char** r = (char**) pp[ndx];
1535 //if (r) {
1536 // for (Int_t v = 0; v < vlen; ++v) {
1537 // cl->Destructor(r[v]);
1538 // r[v] = 0;
1539 // }
1540 //}
1541 delete[] pp[ndx];
1542 pp[ndx] = 0;
1543 }
1544 if (!vlen) {
1545 continue;
1546 }
1547 // Note: We now have pp[ndx] is null.
1548 // Allocate memory to read into.
1549 if (!isPtrPtr) {
1550 // -- We are a varying-length array of objects.
1551 // Note: Polymorphism is not allowed here.
1552 // Allocate a new array of objects to read into.
1553 pp[ndx] = (char*) cl->NewArray(vlen);
1554 if (!pp[ndx]) {
1555 Error("ReadBuffer", "Memory allocation failed!\n");
1556 continue;
1557 }
1558 } else {
1559 // -- We are a varying-length array of pointers to objects.
1560 // Note: The object pointers are allowed to be polymorphic.
1561 // Allocate a new array of pointers to objects to read into.
1562 pp[ndx] = (char*) new char*[vlen];
1563 if (!pp[ndx]) {
1564 Error("ReadBuffer", "Memory allocation failed!\n");
1565 continue;
1566 }
1567 // And set each pointer to null.
1568 memset(pp[ndx], 0, vlen * sizeof(char*)); // This is the right size we really have a char**: pp[ndx] = (char*) new char*[vlen];
1569 }
1570 if (!isPtrPtr) {
1571 // -- We are a varying-length array of objects.
1572 b.ReadFastArray(pp[ndx], cl, vlen, 0);
1573 }
1574 else {
1575 // -- We are a varying-length array of object pointers.
1576 b.ReadFastArray((void**) pp[ndx], cl, vlen, kFALSE, 0);
1577 } // isPtrPtr
1578 } // ndx
1579 } // k
1580 }
1581 else {
1582 // -- Older versions do *not* allow polymorphic pointers.
1583 // Loop over the entries in the clones array or the STL container.
1584 for (Int_t k = 0; k < narr; ++k) {
1585 // Get the counter for the varying length array.
1586 Int_t vlen = *((Int_t*) (arr[k] /*entry pointer*/ + eoffset /*entry offset*/ + compinfo[i]->fMethod /*counter offset*/));
1587 //Int_t realLen;
1588 //b >> realLen;
1589 //if (realLen != vlen) {
1590 // fprintf(stderr, "read vlen: %d realLen: %s\n", vlen, realLen);
1591 //}
1592 // Get a pointer to the array of pointers.
1593 char** pp = (char**) (arr[k] /*entry pointer*/ + ioffset /*object offset*/);
1594 if (!pp) {
1595 continue;
1596 }
1597 // Loop over each element of the array of pointers to varying-length arrays.
1598 for (Int_t ndx = 0; ndx < compinfo[i]->fLength; ++ndx) {
1599 //if (!pp[ndx]) {
1600 // -- We do not have a pointer to a varying-length array.
1601 //Error("ReadBuffer", "The pointer to element %s::%s type %d (%s) is null\n", thisVar->GetName(), aElement->GetFullName(), compinfo[i]->fType, aElement->GetTypeName());
1602 //continue;
1603 //}
1604 // Delete any memory at pp[ndx].
1605 if (!isPtrPtr) {
1606 cl->DeleteArray(pp[ndx]);
1607 pp[ndx] = 0;
1608 } else {
1609 // Using vlen is wrong here because it has already
1610 // been overwritten with the value needed to read
1611 // the current record. Fixing this will require
1612 // doing a pass over the object at the beginning
1613 // of the I/O and releasing all the buffer memory
1614 // for varying length arrays before we overwrite
1615 // the counter values.
1616 //
1617 // For now we will just leak memory, just as we
1618 // have always done in the past. Fix this.
1619 //
1620 //char** r = (char**) pp[ndx];
1621 //if (r) {
1622 // for (Int_t v = 0; v < vlen; ++v) {
1623 // cl->Destructor(r[v]);
1624 // r[v] = 0;
1625 // }
1626 //}
1627 delete[] pp[ndx];
1628 pp[ndx] = 0;
1629 }
1630 if (!vlen) {
1631 continue;
1632 }
1633 // Note: We now have pp[ndx] is null.
1634 // Allocate memory to read into.
1635 if (!isPtrPtr) {
1636 // -- We are a varying-length array of objects.
1637 // Note: Polymorphism is not allowed here.
1638 // Allocate a new array of objects to read into.
1639 pp[ndx] = (char*) cl->NewArray(vlen);
1640 if (!pp[ndx]) {
1641 Error("ReadBuffer", "Memory allocation failed!\n");
1642 continue;
1643 }
1644 } else {
1645 // -- We are a varying-length array of pointers to objects.
1646 // Note: The object pointers are allowed to be polymorphic.
1647 // Allocate a new array of pointers to objects to read into.
1648 pp[ndx] = (char*) new char*[vlen];
1649 if (!pp[ndx]) {
1650 Error("ReadBuffer", "Memory allocation failed!\n");
1651 continue;
1652 }
1653 // And set each pointer to null.
1654 memset(pp[ndx], 0, vlen * sizeof(char*)); // This is the right size we really have a char**: pp[ndx] = (char*) new char*[vlen];
1655 }
1656 if (!isPtrPtr) {
1657 // -- We are a varying-length array of objects.
1658 // Loop over the elements of the varying length array.
1659 for (Int_t v = 0; v < vlen; ++v) {
1660 // Read the object from the buffer.
1661 cl->Streamer(pp[ndx] + (v * cl->Size()), b);
1662 } // v
1663 }
1664 else {
1665 // -- We are a varying-length array of object pointers.
1666 // Get a pointer to the object pointer array.
1667 char** r = (char**) pp[ndx];
1668 // Loop over the elements of the varying length array.
1669 for (Int_t v = 0; v < vlen; ++v) {
1670 // Allocate an object to read into.
1671 r[v] = (char*) cl->New();
1672 if (!r[v]) {
1673 // Do not print a second error message here.
1674 //Error("ReadBuffer", "Memory allocation failed!\n");
1675 continue;
1676 }
1677 // Read the object from the buffer.
1678 cl->Streamer(r[v], b);
1679 } // v
1680 } // isPtrPtr
1681 } // ndx
1682 } // k
1683 } // fileVersion
1684 b.CheckByteCount(start, count, aElement->GetFullName());
1685 continue;
1686 }
1687
1689 ((TBufferFile&)b).PushDataCache( new TVirtualArray( aElement->GetClassPointer(), narr ) );
1690 continue;
1692 delete ((TBufferFile&)b).PopDataCache();
1693 continue;
1694
1695 case -1:
1696 // -- Skip an ignored TObject base class.
1697 continue;
1698
1699 default: {
1700 int ans = -1;
1701
1702 if (TStreamerInfo::kCache <= kase && kase < TStreamerInfo::kArtificial) {
1703
1704 //T &cache_add = *(T*)b.PeekDataCacheArray();
1705 R__ASSERT(kFALSE); // cache_add);
1706
1707 // thisVar->ReadBuffer(b,cache_addr,i,kase-TStreamerInfo::kCache,aElement,narr,eoffset)
1708
1709 continue;
1710 }
1711
1712 if (kase >= TStreamerInfo::kConv)
1713 ans = thisVar->ReadBufferConv(b,arr,compinfo[i],kase,aElement,narr,eoffset);
1714 if (ans==0) continue;
1715
1716 if (kase >= TStreamerInfo::kSkip)
1717 ans = thisVar->ReadBufferSkip(b,arr,compinfo[i],kase,aElement,narr,eoffset);
1718 if (ans==0) continue;
1719
1720 if (kase >= TStreamerInfo::kArtificial) {
1721 ans = thisVar->ReadBufferArtificial(b,arr,aElement,narr,eoffset);
1722 }
1723 if (ans==0) continue;
1724 }
1725 if (aElement)
1726 Error("ReadBuffer","The element %s::%s type %d (%s) is not supported yet\n",
1727 thisVar->GetName(),aElement->GetFullName(),kase,aElement->GetTypeName());
1728 else
1729 Error("ReadBuffer","The TStreamerElement for %s %d is missing!\n",
1730 thisVar->GetName(),i);
1731
1732 continue;
1733 }
1734 }
1735 if (needIncrement) b.DecrementLevel(thisVar);
1736 return 0;
1737}
1738
1739template Int_t TStreamerInfo::ReadBufferSkip<char**>(TBuffer &b, char** const &arr, const TCompInfo *compinfo, Int_t kase,
1740 TStreamerElement *aElement, Int_t narr,
1741 Int_t eoffset);
1742template Int_t TStreamerInfo::ReadBufferSkip<TVirtualCollectionProxy>(TBuffer &b, const TVirtualCollectionProxy &arr, const TCompInfo *compinfo, Int_t kase,
1743 TStreamerElement *aElement, Int_t narr,
1744 Int_t eoffset);
1745template Int_t TStreamerInfo::ReadBufferSkip<TVirtualArray>(TBuffer &b, const TVirtualArray &arr, const TCompInfo *compinfo, Int_t kase,
1746 TStreamerElement *aElement, Int_t narr,
1747 Int_t eoffset);
1748
1749template Int_t TStreamerInfo::ReadBufferConv<char**>(TBuffer &b, char** const &arr, const TCompInfo *compinfo, Int_t kase,
1750 TStreamerElement *aElement, Int_t narr,
1751 Int_t eoffset);
1752template Int_t TStreamerInfo::ReadBufferConv<TVirtualCollectionProxy>(TBuffer &b, const TVirtualCollectionProxy &arr, const TCompInfo *compinfo, Int_t kase,
1753 TStreamerElement *aElement, Int_t narr,
1754 Int_t eoffset);
1755template Int_t TStreamerInfo::ReadBufferConv<TVirtualArray>(TBuffer &b, const TVirtualArray &arr, const TCompInfo *compinfo, Int_t kase,
1756 TStreamerElement *aElement, Int_t narr,
1757 Int_t eoffset);
1758
1759template Int_t TStreamerInfo::ReadBufferArtificial<char**>(TBuffer &b, char** const &arr,
1760 TStreamerElement *aElement, Int_t narr,
1761 Int_t eoffset);
1762template Int_t TStreamerInfo::ReadBufferArtificial<TVirtualCollectionProxy>(TBuffer &b, const TVirtualCollectionProxy &arr,
1763 TStreamerElement *aElement, Int_t narr,
1764 Int_t eoffset);
1765template Int_t TStreamerInfo::ReadBufferArtificial<TVirtualArray>(TBuffer &b, const TVirtualArray &arr,
1766 TStreamerElement *aElement, Int_t narr,
1767 Int_t eoffset);
1768
1769template Int_t TStreamerInfo::ReadBuffer<char**>(TBuffer &b, char** const &arr,
1770 TCompInfo *const*const compinfo, Int_t first, Int_t last,
1771 Int_t narr, Int_t eoffset, Int_t arrayMode);
1772template Int_t TStreamerInfo::ReadBuffer<TVirtualCollectionProxy>(TBuffer &b, const TVirtualCollectionProxy &arr,
1773 TCompInfo *const*const compinfo, Int_t first, Int_t last,
1774 Int_t narr, Int_t eoffset, Int_t arrayMode);
1775template Int_t TStreamerInfo::ReadBuffer<TVirtualArray>(TBuffer &b, const TVirtualArray &arr,
1776 TCompInfo *const*const compinfo, Int_t first, Int_t last,
1777 Int_t narr, Int_t eoffset, Int_t arrayMode);
1778
1779////////////////////////////////////////////////////////////////////////////////
1780/// The STL vector/list is deserialized from the buffer b
1781
1783 Int_t nc, Int_t eoffset, Bool_t v7 /* = kTRUE */)
1784{
1785 if (!nc && v7) return 0; // in version 6 of TStreamerInfo and below, we were calling ReadBuffer for empty collection.
1786 int ret = ReadBuffer(b, *cont,fCompFull,0,fNfulldata,nc,eoffset,1);
1787 return ret;
1788}
1789
1790////////////////////////////////////////////////////////////////////////////////
1791/// Read for TClonesArray.
1792/// Note: This is no longer used.
1793
1795 Int_t nc, Int_t first, Int_t eoffset)
1796{
1797 char **arr = (char **)clones->GetObjectRef(0);
1798 return ReadBuffer(b,arr,fCompFull,first==-1?0:first,first==-1?fNfulldata:first+1,nc,eoffset,1);
1799}
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
bool Bool_t
Definition RtypesCore.h:63
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
constexpr Int_t kMaxInt
Definition RtypesCore.h:105
short Version_t
Definition RtypesCore.h:65
unsigned char UChar_t
Definition RtypesCore.h:38
char Char_t
Definition RtypesCore.h:37
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:69
unsigned long long ULong64_t
Definition RtypesCore.h:70
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
#define DOLOOP(x)
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
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 r
Int_t gDebug
Definition TROOT.cxx:597
#define ReadBasicArray(name)
#define ConvCBasicPointer(name, ReadArrayFunc)
#define SkipCBasicPointer(name, ReadArrayFunc)
#define ReadBasicType(name)
#define ReadBasicPointerLoop(name)
static TStreamerElement *& CurrentElement()
#define ReadBasicArrayLoop(name)
#define SkipCFloat16(name)
#define ReadBasicTypeLoop(name)
#define SkipCBasicArray(name, ReadArrayFunc)
#define ConvCBasicArray(name, ReadArrayFunc)
#define SkipCDouble32(name)
#define ConvCBasicType(name, stream)
#define ReadBasicPointer(name)
#define SkipCBasicType(name)
void(* ReadFuncPtr_t)(char *, TVirtualObject *)
Definition TSchemaRule.h:40
void(* ReadRawFuncPtr_t)(char *, TBuffer &)
Definition TSchemaRule.h:41
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
Definition TBufferFile.h:47
@ kStreamedMemberWise
Definition TBufferFile.h:69
Buffer base class used for serializing objects.
Definition TBuffer.h:43
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
void Streamer(void *obj, TBuffer &b, const TClass *onfile_class=nullptr) const
Definition TClass.h:608
void * NewArray(Long_t nElements, ENewType defConstructor=kClassNew) const
Return a pointer to a newly allocated array of objects of this class.
Definition TClass.cxx:5274
EState GetState() const
Definition TClass.h:489
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5059
Bool_t IsStartingWithTObject() const
Returns true if this class inherits from TObject and if the start of the TObject parts is at the very...
Definition TClass.cxx:6010
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5785
void DeleteArray(void *ary, Bool_t dtorOnly=kFALSE)
Explicitly call operator delete[] for an array.
Definition TClass.cxx:5610
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0, Bool_t isTransient=kFALSE) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Definition TClass.cxx:4668
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2966
TVirtualStreamerInfo * GetConversionStreamerInfo(const char *onfile_classname, Int_t version) const
Return a Conversion StreamerInfo from the class 'classname' for version number 'version' to this clas...
Definition TClass.cxx:7167
@ kEmulated
Definition TClass.h:125
An array of clone (identical) objects.
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:53
Int_t GetVersion() const
Definition TFile.h:245
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
void Streamer(TBuffer &) override
Stream an object of class TObject.
TObject ** GetObjectRef() const
Definition TObjArray.h:63
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:474
@ kIsOnHeap
object is on heap
Definition TObject.h:81
@ kNotDeleted
object has not been deleted
Definition TObject.h:82
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:906
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:225
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:991
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1005
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:809
@ kIsReferenced
if object is referenced by a TRef or TRefArray
Definition TObject.h:65
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition TProcessID.h:74
void PutObjectWithID(TObject *obj, UInt_t uid=0)
stores the object at the uid th slot in the table of objects The object uniqued is set as well as its...
Persistent Reference link to a TObject A TRef is a lightweight object pointing to any TObject.
Definition TRef.h:32
void Streamer(TBuffer &) override
Stream an object of class TRef.
Definition TRef.cxx:486
static TClass * Class()
ROOT::TSchemaRule::ReadRawFuncPtr_t GetReadRawFunc()
ROOT::TSchemaRule::ReadFuncPtr_t GetReadFunc()
static TClass * Class()
virtual const char * GetFullName() const
Return element name including dimensions, if any Note that this function stores the name into a stati...
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
TClass * GetNewClass() const
void ls(Option_t *option="") const override
Print the content of the element.
const char * GetTypeName() const
TClass * IsA() const override
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
virtual void SetTObjectOffset(Int_t tobjoffset)
TClass * fClass
Not Owned.
TMemberStreamer * fStreamer
Not Owned.
TClass * fNewClass
Not Owned.
Describes a persistent version of a class.
Int_t ReadBufferSTL(TBuffer &b, TVirtualCollectionProxy *cont, Int_t nc, Int_t eoffset, Bool_t v7=kTRUE)
The STL vector/list is deserialized from the buffer b.
Int_t fNfulldata
!number of elements
TCompInfo ** fCompFull
![fElements->GetEntries()]
Int_t ReadBuffer(TBuffer &b, const T &arrptr, TCompInfo *const *const compinfo, Int_t first, Int_t last, Int_t narr=1, Int_t eoffset=0, Int_t mode=0)
Deserialize information from buffer b into object at pointer if (arrayMode & 1) ptr is a pointer to a...
Int_t ReadBufferConv(TBuffer &b, const T &arrptr, const TCompInfo *compinfo, Int_t kase, TStreamerElement *aElement, Int_t narr, Int_t eoffset)
Convert elements of a TClonesArray.
Int_t ReadBufferClones(TBuffer &b, TClonesArray *clones, Int_t nc, Int_t first, Int_t eoffset)
Read for TClonesArray.
TClass * IsA() const override
TClass * fClass
!pointer to class
void Streamer(TBuffer &) override
Stream an object of class TStreamerInfo.
static TStreamerElement * GetCurrentElement()
static function returning a pointer to the current TStreamerElement fgElement points to the current T...
Int_t ReadBufferArtificial(TBuffer &b, const T &arrptr, TStreamerElement *aElement, Int_t narr, Int_t eoffset)
Handle Artificial StreamerElement.
Int_t ReadBufferSkip(TBuffer &b, const T &arrptr, const TCompInfo *compinfo, Int_t kase, TStreamerElement *aElement, Int_t narr, Int_t eoffset)
Skip an element.
Version_t fOldVersion
! Version of the TStreamerInfo object read from the file
Basic string class.
Definition TString.h:139
virtual void Streamer(TBuffer &)
Stream a string object.
Definition TString.cxx:1412
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
char * GetObjectAt(UInt_t ind) const
TClassRef fClass
RAII helper class that ensures that PushProxy() / PopProxy() are called when entering / leaving a C++...
Defines a common interface to inspect/change the contents of an object that represents a collection.
virtual TStreamerInfoActions::TActionSequence * GetReadMemberWiseActions(Int_t version)=0
virtual TClass * GetValueClass() const =0
If the value type is a user-defined class, return a pointer to the TClass representing the value type...
virtual void Commit(void *)=0
Commits pending elements in a staging area (see Allocate() for more information).
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
static const Int_t fgIteratorArenaSize
The size of a small buffer that can be allocated on the stack to store iterator-specific information.
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
Return a pointer to a function that can create an iterator pair, where each iterator points to the be...
virtual void * Allocate(UInt_t n, Bool_t forceDelete)=0
Allocates space for storing at least n elements.
virtual TStreamerInfoActions::TActionSequence * GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version)=0
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
@ kUChar
Equal to TDataType's kchar.
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TLine l
Definition textangle.C:4