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