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 if ((u & kIsReferenced) != 0) {
613 UShort_t pidf;
614 b >> pidf;
615 pidf += b.GetPidOffset();
616 TProcessID *pid = b.ReadProcessID(pidf);
617 if (pid!=0) {
618 TObject *obj = (TObject*)(arr[k]+eoffset);
619 UInt_t gpid = pid->GetUniqueID();
620 UInt_t uid;
621 if (gpid>=0xff) {
622 uid = obj->GetUniqueID() | 0xff000000;
623 } else {
624 uid = ( obj->GetUniqueID() & 0xffffff) + (gpid<<24);
625 }
626 obj->SetUniqueID(uid);
627 pid->PutObjectWithID(obj);
628 }
629 }
630 switch(compinfo->fNewType) {
631 case TStreamerInfo::kBool: {Bool_t *x=(Bool_t*)(arr[k]+ioffset); *x = (Bool_t)u; break;}
632 case TStreamerInfo::kChar: {Char_t *x=(Char_t*)(arr[k]+ioffset); *x = (Char_t)u; break;}
633 case TStreamerInfo::kShort: {Short_t *x=(Short_t*)(arr[k]+ioffset); *x = (Short_t)u; break;}
634 case TStreamerInfo::kInt: {Int_t *x=(Int_t*)(arr[k]+ioffset); *x = (Int_t)u; break;}
635 case TStreamerInfo::kLong: {Long_t *x=(Long_t*)(arr[k]+ioffset); *x = (Long_t)u; break;}
636 case TStreamerInfo::kLong64: {Long64_t *x=(Long64_t*)(arr[k]+ioffset); *x = (Long64_t)u; break;}
637 case TStreamerInfo::kFloat: {Float_t *x=(Float_t*)(arr[k]+ioffset); *x = (Float_t)u; break;}
638 case TStreamerInfo::kFloat16: {Float_t *x=(Float_t*)(arr[k]+ioffset); *x = (Float_t)u; break;}
639 case TStreamerInfo::kDouble: {Double_t *x=(Double_t*)(arr[k]+ioffset); *x = (Double_t)u; break;}
640 case TStreamerInfo::kDouble32:{Double_t *x=(Double_t*)(arr[k]+ioffset); *x = (Double_t)u; break;}
641 case TStreamerInfo::kUChar: {UChar_t *x=(UChar_t*)(arr[k]+ioffset); *x = (UChar_t)u; break;}
642 case TStreamerInfo::kUShort: {UShort_t *x=(UShort_t*)(arr[k]+ioffset); *x = (UShort_t)u; break;}
643 case TStreamerInfo::kUInt: {UInt_t *x=(UInt_t*)(arr[k]+ioffset); *x = (UInt_t)u; break;}
644 case TStreamerInfo::kULong: {ULong_t *x=(ULong_t*)(arr[k]+ioffset); *x = (ULong_t)u; break;}
645 case TStreamerInfo::kULong64: {ULong64_t*x=(ULong64_t*)(arr[k]+ioffset);*x = (ULong64_t)u;break;}
646 }
647 } break;
648 }
649
650 // convert array of basic types array[8]
657 ConvCBasicArray(Long64_t,ReadFastArray);
658 } else {
659 ConvCBasicArray(Long_t,ReadFastArray);
660 }
671#if defined(_MSC_VER) && (_MSC_VER <= 1200)
672 ConvCBasicArray(Long64_t,ReadFastArray)
673#else
674 ConvCBasicArray(ULong64_t,ReadFastArray)
675#endif
676 } else {
677 ConvCBasicArray(ULong_t,ReadFastArray);
678 }
679#if defined(_MSC_VER) && (_MSC_VER <= 1200)
681#else
683#endif
684
685 // convert pointer to an array of basic types array[n]
692 ConvCBasicPointer(Long64_t,ReadFastArray);
693 } else {
694 ConvCBasicPointer(Long_t,ReadFastArray);
695 }
706#if defined(_MSC_VER) && (_MSC_VER <= 1200)
707 ConvCBasicPointer(Long64_t,ReadFastArray)
708#else
709 ConvCBasicPointer(ULong64_t,ReadFastArray)
710#endif
711 } else {
712 ConvCBasicPointer(ULong_t,ReadFastArray);
713 }
714#if defined(_MSC_VER) && (_MSC_VER <= 1200)
716#else
718#endif
719
720 default:
721 // Warning("ReadBufferConv","The element type %d is not supported yet",compinfo->fType);
722 return -1;
723
724 }
725
726 return 0;
727}
728
729// Helper function for TStreamerInfo::ReadBuffer
730namespace {
731 template <class T> Bool_t R__TestUseCache(TStreamerElement *element)
732 {
733 return element->TestBit(TStreamerElement::kCache);
734 }
735
736 template <> Bool_t R__TestUseCache<TVirtualArray>(TStreamerElement*)
737 {
738 // We are already using the cache, no need to recurse one more time.
739 return kFALSE;
740 }
741}
742
743////////////////////////////////////////////////////////////////////////////////
744/// Deserialize information from buffer b into object at pointer
745/// if (arrayMode & 1) ptr is a pointer to array of pointers to the objects
746/// otherwise it is a pointer to a pointer to a single object.
747/// This also means that T is of a type such that arr[i] is a pointer to an
748/// object. Currently the only anticipated instantiation are for T==char**
749/// and T==TVirtualCollectionProxy
750
751template <class T>
753 TCompInfo *const*const compinfo, Int_t first, Int_t last,
754 Int_t narr, Int_t eoffset, Int_t arrayMode)
755{
756 TStreamerInfo *thisVar = this;
757 Bool_t needIncrement = !( arrayMode & 2 );
758 arrayMode = arrayMode & (~2);
759
760 if (needIncrement) b.IncrementLevel(thisVar);
761
762 //loop on all active members
763
764 // In order to speed up the case where the object being written is
765 // not in a collection (i.e. arrayMode is false), we actually
766 // duplicate the code for the elementary types using this typeOffset.
767 static const int kHaveLoop = 1024;
768 const Int_t typeOffset = arrayMode ? kHaveLoop : 0;
769
770 TClass *cle = 0;
771 TClass *newCle = 0;
772 TMemberStreamer *pstreamer=0;
773 Int_t isPreAlloc = 0;
774 for (Int_t i=first;i<last;i++) {
775 TStreamerElement * aElement = (TStreamerElement*)compinfo[i]->fElem;
776 CurrentElement() = aElement;
777
778 if (needIncrement) b.SetStreamerElementNumber(aElement,compinfo[i]->fType);
779
780 if (aElement->TestBit(TStreamerElement::kWrite)) continue;
781
782 if (R__TestUseCache<T>(aElement)) {
783 Int_t bufpos = b.Length();
784 if (((TBufferFile&)b).PeekDataCache()==0) {
785 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",thisVar->GetName(),aElement->GetName());
786 thisVar->ReadBufferSkip(b,arr,compinfo[i],compinfo[i]->fType+TStreamerInfo::kSkip,aElement,narr,eoffset);
787 } else {
788 if (gDebug > 1) {
789 printf("ReadBuffer, class:%s, name=%s, fType[%d]=%d,"
790 " %s, bufpos=%d, arr=%p, eoffset=%d, Redirect=%p\n",
791 fClass->GetName(),aElement->GetName(),i,compinfo[i]->fType,
792 aElement->ClassName(),b.Length(),arr[0], eoffset,((TBufferFile&)b).PeekDataCache()->GetObjectAt(0));
793 }
794 thisVar->ReadBuffer(b,*((TBufferFile&)b).PeekDataCache(),compinfo,i,i+1,narr,eoffset, arrayMode);
795 }
796 if (aElement->TestBit(TStreamerElement::kRepeat)) { b.SetBufferOffset(bufpos); }
797 continue;
798 }
799 const Int_t ioffset = compinfo[i]->fOffset+eoffset;
800
801 if (gDebug > 1) {
802 printf("ReadBuffer, class:%s, name=%s, fType[%d]=%d,"
803 " %s, bufpos=%d, arr=%p, offset=%d\n",
804 fClass->GetName(),aElement->GetName(),i,compinfo[i]->fType,
805 aElement->ClassName(),b.Length(),arr[0], ioffset);
806 }
807
808 Int_t kase = compinfo[i]->fType;
809
810 switch (kase + typeOffset) {
811
812 // read basic types
816 case TStreamerInfo::kInt: ReadBasicType(Int_t); continue;
827 Float_t *x=(Float_t*)(arr[0]+ioffset);
828 b.ReadFloat16(x,aElement);
829 continue;
830 }
832 Double_t *x=(Double_t*)(arr[0]+ioffset);
833 b.ReadDouble32(x,aElement);
834 continue;
835 }
836
837 case TStreamerInfo::kBool + kHaveLoop: ReadBasicTypeLoop(Bool_t); continue;
838 case TStreamerInfo::kChar + kHaveLoop: ReadBasicTypeLoop(Char_t); continue;
839 case TStreamerInfo::kShort + kHaveLoop: ReadBasicTypeLoop(Short_t); continue;
840 case TStreamerInfo::kInt + kHaveLoop: ReadBasicTypeLoop(Int_t); continue;
841 case TStreamerInfo::kLong + kHaveLoop: ReadBasicTypeLoop(Long_t); continue;
842 case TStreamerInfo::kLong64 + kHaveLoop: ReadBasicTypeLoop(Long64_t); continue;
843 case TStreamerInfo::kFloat + kHaveLoop: ReadBasicTypeLoop(Float_t); continue;
844 case TStreamerInfo::kDouble + kHaveLoop: ReadBasicTypeLoop(Double_t); continue;
845 case TStreamerInfo::kUChar + kHaveLoop: ReadBasicTypeLoop(UChar_t); continue;
846 case TStreamerInfo::kUShort + kHaveLoop: ReadBasicTypeLoop(UShort_t); continue;
847 case TStreamerInfo::kUInt + kHaveLoop: ReadBasicTypeLoop(UInt_t); continue;
848 case TStreamerInfo::kULong + kHaveLoop: ReadBasicTypeLoop(ULong_t); continue;
849 case TStreamerInfo::kULong64+ kHaveLoop: ReadBasicTypeLoop(ULong64_t); continue;
850 case TStreamerInfo::kFloat16 + kHaveLoop: {
851 for(Int_t k=0; k<narr; ++k) {
852 Float_t *x=(Float_t*)(arr[k]+ioffset);
853 b.ReadFloat16(x,aElement);
854 }
855 continue;
856 }
857 case TStreamerInfo::kDouble32 + kHaveLoop: {
858 for(Int_t k=0; k<narr; ++k) {
859 Double_t *x=(Double_t*)(arr[k]+ioffset);
860 b.ReadDouble32(x,aElement);
861 }
862 continue;
863 }
864
865 // read array of basic types like array[8]
880 b.ReadFastArrayFloat16((Float_t*)(arr[0]+ioffset),compinfo[i]->fLength,aElement);
881 continue;
882 }
884 b.ReadFastArrayDouble32((Double_t*)(arr[0]+ioffset),compinfo[i]->fLength,aElement);
885 continue;
886 }
887
902 for(Int_t k=0; k<narr; ++k) {
903 b.ReadFastArrayFloat16((Float_t*)(arr[k]+ioffset),compinfo[i]->fLength,aElement);
904 }
905 continue;
906 }
908 for(Int_t k=0; k<narr; ++k) {
909 b.ReadFastArrayDouble32((Double_t*)(arr[k]+ioffset),compinfo[i]->fLength,aElement);
910 }
911 continue;
912 }
913
914 // read pointer to an array of basic types array[n]
929 Char_t isArray;
930 b >> isArray;
931 const int imethod = compinfo[i]->fMethod+eoffset;
932 Int_t *l = (Int_t*)(arr[0]+imethod);
933 Float_t **f = (Float_t**)(arr[0]+ioffset);
934 int j;
935 for(j=0;j<compinfo[i]->fLength;j++) {
936 delete [] f[j];
937 f[j] = 0; if (*l <=0) continue;
938 f[j] = new Float_t[*l];
939 b.ReadFastArrayFloat16(f[j],*l,aElement);
940 }
941 continue;
942 }
944 Char_t isArray;
945 b >> isArray;
946 const int imethod = compinfo[i]->fMethod+eoffset;
947 Int_t *l = (Int_t*)(arr[0]+imethod);
948 Double_t **f = (Double_t**)(arr[0]+ioffset);
949 int j;
950 for(j=0;j<compinfo[i]->fLength;j++) {
951 delete [] f[j];
952 f[j] = 0; if (*l <=0) continue;
953 f[j] = new Double_t[*l];
954 b.ReadFastArrayDouble32(f[j],*l,aElement);
955 }
956 continue;
957 }
958
973 const int imethod = compinfo[i]->fMethod+eoffset;
974 for(Int_t k=0; k<narr; ++k) {
975 Char_t isArray;
976 b >> isArray;
977 Int_t *l = (Int_t*)(arr[k]+imethod);
978 Float_t **f = (Float_t**)(arr[k]+ioffset);
979 int j;
980 for(j=0;j<compinfo[i]->fLength;j++) {
981 delete [] f[j];
982 f[j] = 0; if (*l <=0) continue;
983 f[j] = new Float_t[*l];
984 b.ReadFastArrayFloat16(f[j],*l,aElement);
985 }
986 }
987 continue;
988 }
990 const int imethod = compinfo[i]->fMethod+eoffset;
991 for(Int_t k=0; k<narr; ++k) {
992 Char_t isArray;
993 b >> isArray;
994 Int_t *l = (Int_t*)(arr[k]+imethod);
995 Double_t **f = (Double_t**)(arr[k]+ioffset);
996 int j;
997 for(j=0;j<compinfo[i]->fLength;j++) {
998 delete [] f[j];
999 f[j] = 0; if (*l <=0) continue;
1000 f[j] = new Double_t[*l];
1001 b.ReadFastArrayDouble32(f[j],*l,aElement);
1002 }
1003 }
1004 continue;
1005 }
1006 }
1007
1008 switch (kase) {
1009
1010 // char*
1012 DOLOOP {
1013 char **f = (char**)(arr[k]+ioffset);
1014 b.ReadCharStar(*f);
1015 }
1016 }
1017 continue;
1018
1019 // special case for TObject::fBits in case of a referenced object
1020 case TStreamerInfo::kBits: {
1021 DOLOOP {
1022 UInt_t *x=(UInt_t*)(arr[k]+ioffset); b >> *x;
1023 if ((*x & kIsReferenced) != 0) {
1024 UShort_t pidf;
1025 b >> pidf;
1026 pidf += b.GetPidOffset();
1027 TProcessID *pid = b.ReadProcessID(pidf);
1028 if (pid!=0) {
1029 TObject *obj = (TObject*)(arr[k]+eoffset);
1030 UInt_t gpid = pid->GetUniqueID();
1031 UInt_t uid;
1032 if (gpid>=0xff) {
1033 uid = obj->GetUniqueID() | 0xff000000;
1034 } else {
1035 uid = ( obj->GetUniqueID() & 0xffffff) + (gpid<<24);
1036 }
1037 obj->SetUniqueID(uid);
1038 pid->PutObjectWithID(obj);
1039 }
1040 }
1041 }
1042 }
1043 continue;
1044
1045 // array counter //[n]
1047 DOLOOP {
1048 Int_t *x=(Int_t*)(arr[k]+ioffset);
1049 b >> *x;
1050 }
1051 }
1052 continue;
1053
1054
1055 // Special case for TString, TObject, TNamed
1056 case TStreamerInfo::kTString: { DOLOOP { ((TString*)(arr[k]+ioffset))->Streamer(b); } } continue;
1057 case TStreamerInfo::kTObject: { DOLOOP { ((TObject*)(arr[k]+ioffset))->TObject::Streamer(b);} } continue;
1058 case TStreamerInfo::kTNamed: { DOLOOP { ((TNamed*) (arr[k]+ioffset))->TNamed::Streamer(b) ;} } continue;
1059
1060 }
1061
1062 SWIT:
1063 isPreAlloc= 0;
1064 cle = compinfo[i]->fClass;
1065 newCle = compinfo[i]->fNewClass;
1066 pstreamer = compinfo[i]->fStreamer;
1067
1068 switch (kase) {
1069
1070 case TStreamerInfo::kAnyp: // Class* not derived from TObject with comment field //->
1072 case TStreamerInfo::kObjectp: // Class* derived from TObject with comment field //->
1074 isPreAlloc = 1;
1075 // Intentional fallthrough now that isPreAlloc is set.
1076 case TStreamerInfo::kObjectP: // Class* derived from TObject with no comment field NOTE: Re-added by Phil
1078 case TStreamerInfo::kAnyP: // Class* not derived from TObject with no comment field NOTE:: Re-added by Phil
1080 DOLOOP {
1081 b.ReadFastArray((void**)(arr[k]+ioffset),cle,compinfo[i]->fLength,isPreAlloc,pstreamer);
1082 }
1083 }
1084 continue;
1085
1086// case TStreamerInfo::kSTLvarp: // Variable size array of STL containers.
1087// {
1088// TMemberStreamer *pstreamer = compinfo[i]->fStreamer;
1089// TClass *cl = compinfo[i]->fClass;
1090// ROOT::NewArrFunc_t arraynew = cl->GetNewArray();
1091// ROOT::DelArrFunc_t arraydel = cl->GetDeleteArray();
1092// UInt_t start,count;
1093// // Version_t v =
1094// b.ReadVersion(&start, &count, cle);
1095// if (pstreamer == 0) {
1096// Int_t size = cl->Size();
1097// Int_t imethod = compinfo[i]->fMethod+eoffset;
1098// DOLOOP {
1099// char **contp = (char**)(arr[k]+ioffset);
1100// const Int_t *counter = (Int_t*)(arr[k]+imethod);
1101// const Int_t sublen = (*counter);
1102
1103// for(int j=0;j<compinfo[i]->fLength;++j) {
1104// if (arraydel) arraydel(contp[j]);
1105// contp[j] = 0;
1106// if (sublen<=0) continue;
1107// if (arraynew) {
1108// contp[j] = (char*)arraynew(sublen, 0);
1109// char *cont = contp[j];
1110// for(int k=0;k<sublen;++k) {
1111// cl->Streamer( cont, b );
1112// cont += size;
1113// }
1114// } else {
1115// // Can't create an array of object
1116// Error("ReadBuffer","The element %s::%s type %d (%s) can be read because of the class does not have access to new %s[..]\n",
1117// GetName(),aElement->GetFullName(),kase,aElement->GetTypeName(),GetName());
1118// void *cont = cl->New();
1119// for(int k=0;k<sublen;++k) {
1120// cl->Streamer( cont, b );
1121// }
1122// }
1123// }
1124// }
1125// } else {
1126// DOLOOP{(*pstreamer)(b,arr[k]+ioffset,compinfo[i]->fLength);}
1127// }
1128// b.CheckByteCount(start,count,aElement->GetFullName());
1129// }
1130// continue;
1131
1132 case TStreamerInfo::kSTLp: // Pointer to Container with no virtual table (stl) and no comment
1133 case TStreamerInfo::kSTLp + TStreamerInfo::kOffsetL: // array of pointers to Container with no virtual table (stl) and no comment
1134 {
1135 UInt_t start,count;
1136 Version_t vers = b.ReadVersion(&start, &count, cle);
1137
1138 if ( vers & TBufferFile::kStreamedMemberWise ) {
1139 // Collection was saved member-wise
1140
1142
1143 TClass *newClass = aElement->GetNewClass();
1144 TClass *oldClass = aElement->GetClassPointer();
1145 if( vers < 9 && newClass && newClass!=oldClass ) {
1146 Error( "ReadBuffer", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
1147 vers, b.GetParent() ? b.GetParent()->GetName() : "memory/socket", oldClass->GetName(), newClass->GetName() );
1148 continue;
1149 }
1150
1151 Version_t vClVersion = 0; // For vers less than 9, we have to use the current version.
1152 if( vers >= 9 ) {
1153 vClVersion = b.ReadVersionForMemberWise( cle->GetCollectionProxy()->GetValueClass() );
1154 }
1155
1156 TVirtualCollectionProxy *newProxy = (newClass ? newClass->GetCollectionProxy() : 0);
1157 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
1158 TStreamerInfo *subinfo = 0;
1159
1160 if( newProxy ) {
1161 // coverity[dereference] oldProxy->GetValueClass() can not be null since this was streamed memberwise.
1162 subinfo = (TStreamerInfo*)newProxy->GetValueClass()->GetConversionStreamerInfo( oldProxy->GetValueClass(), vClVersion );
1163 } else {
1164 subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( vClVersion );
1165 newProxy = oldProxy;
1166 }
1167 if (subinfo) {
1168 DOLOOP {
1169 void* env;
1170 void **contp = (void**)(arr[k]+ioffset);
1171 int j;
1172 for(j=0;j<compinfo[i]->fLength;j++) {
1173 void *cont = contp[j];
1174 if (cont==0) {
1175 contp[j] = cle->New();
1176 cont = contp[j];
1177 }
1178 TVirtualCollectionProxy::TPushPop helper( newProxy, cont );
1179 Int_t nobjects;
1180 b >> nobjects;
1181 env = newProxy->Allocate(nobjects,true);
1182 subinfo->ReadBufferSTL(b,newProxy,nobjects,/* offset */ 0, vers>=7 );
1183 newProxy->Commit(env);
1184 }
1185 }
1186 }
1187 b.CheckByteCount(start,count,aElement->GetFullName());
1188 continue;
1189 }
1190 if (pstreamer == 0) {
1191 DOLOOP {
1192 void **contp = (void**)(arr[k]+ioffset);
1193 int j;
1194 for(j=0;j<compinfo[i]->fLength;j++) {
1195 void *cont = contp[j];
1196 if (cont==0) {
1197 // int R__n;
1198 // b >> R__n;
1199 // b.SetOffset(b.GetOffset()-4); // rewind to the start of the int
1200 // if (R__n) continue;
1201 contp[j] = cle->New();
1202 cont = contp[j];
1203 }
1204 cle->Streamer( cont, b );
1205 }
1206 }
1207 } else {
1208 DOLOOP {(*pstreamer)(b,arr[k]+ioffset,compinfo[i]->fLength);}
1209 }
1210 b.CheckByteCount(start,count,aElement->GetFullName());
1211 }
1212 continue;
1213
1214 case TStreamerInfo::kSTL: // Container with no virtual table (stl) and no comment
1215 case TStreamerInfo::kSTL + TStreamerInfo::kOffsetL: // array of Container with no virtual table (stl) and no comment
1216 {
1217 UInt_t start, count;
1218 Version_t vers = b.ReadVersion(&start, &count, cle);
1219
1220 if ( vers & TBufferFile::kStreamedMemberWise ) {
1221 // Collection was saved member-wise
1223
1224 TClass *newClass = aElement->GetNewClass();
1225 TClass *oldClass = aElement->GetClassPointer();
1226
1227 if( vers < 8 && newClass && newClass!=oldClass ) {
1228 Error( "ReadBuffer", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
1229 vers, b.GetParent() ? b.GetParent()->GetName() : "memory/socket", oldClass->GetName(), newClass->GetName() );
1230 continue;
1231 }
1232 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
1233 TClass *valueClass = oldProxy ? oldProxy->GetValueClass() : 0;
1234 Version_t vClVersion = 0; // For vers less than 8, we have to use the current version.
1235 if( vers >= 8 ) {
1236 vClVersion = b.ReadVersionForMemberWise( valueClass );
1237 }
1238
1239 if (valueClass == 0) {
1240 // MemberWise streaming applies to only collection of classes, and hence
1241 // valueClass can only be null if we are reading without the original library
1242 // and the collection is always empty,
1243 // So let's skip the rest (which requires the StreamerInfo of the valueClass ... which we do not have)
1244
1245 b.SetBufferOffset(start+count+sizeof(UInt_t));
1246 continue;
1247 }
1248
1249 TVirtualCollectionProxy *newProxy = (newClass ? newClass->GetCollectionProxy() : 0);
1250 TStreamerInfo *subinfo = 0;
1251
1252 if( newProxy ) {
1253 // coverity[dereference] oldProxy->GetValueClass() can not be null since this was streamed memberwise.
1254 subinfo = (TStreamerInfo*)newProxy->GetValueClass()->GetConversionStreamerInfo( oldProxy->GetValueClass(), vClVersion );
1255 } else {
1256 subinfo = (TStreamerInfo*)valueClass->GetStreamerInfo( vClVersion );
1257 newProxy = oldProxy;
1258 }
1259 if (subinfo) {
1260 DOLOOP {
1261 int objectSize = cle->Size();
1262 char *obj = arr[k]+ioffset;
1263 char *end = obj + compinfo[i]->fLength*objectSize;
1264
1265 for(; obj<end; obj+=objectSize) {
1266 TVirtualCollectionProxy::TPushPop helper( newProxy, obj );
1267 Int_t nobjects;
1268 b >> nobjects;
1269 void* env = newProxy->Allocate(nobjects,true);
1270 subinfo->ReadBufferSTL(b,newProxy,nobjects,/* offset */ 0, vers >= 7);
1271 newProxy->Commit(env);
1272 }
1273 }
1274 }
1275 b.CheckByteCount(start,count,aElement->GetTypeName());
1276 continue;
1277 }
1278 if (fOldVersion<3){ // case of old TStreamerInfo
1279 // Backward compatibility. Some TStreamerElement's where without
1280 // Streamer but were not removed from element list
1281 if (aElement->IsBase() && aElement->IsA()!=TStreamerBase::Class()) {
1282 b.SetBufferOffset(start); //there is no byte count
1283 } else if (vers==0) {
1284 b.SetBufferOffset(start); //there is no byte count
1285 }
1286 }
1287 if (pstreamer == 0) {
1288 if( !newCle ) {
1289 newCle = cle;
1290 cle = 0;
1291 }
1292 DOLOOP {
1293 b.ReadFastArray((void*)(arr[k]+ioffset),newCle,compinfo[i]->fLength,(TMemberStreamer*)0, cle );
1294 }
1295 } else {
1296 DOLOOP {(*pstreamer)(b,arr[k]+ioffset,compinfo[i]->fLength);}
1297 }
1298 b.CheckByteCount(start,count,aElement->GetTypeName());
1299 }
1300 continue;
1301
1302 case TStreamerInfo::kObject: // Class derived from TObject
1303 if (cle->IsStartingWithTObject() && cle->GetState() > TClass::kEmulated) {
1304 DOLOOP {((TObject*)(arr[k]+ioffset))->Streamer(b);}
1305 continue; // intentionally inside the if statement.
1306 // if the class does not start with its TObject part (or does
1307 // not have one), we use the generic case.
1308 }
1309 case TStreamerInfo::kAny: // Class not derived from TObject
1310 if (pstreamer) {
1311 DOLOOP {(*pstreamer)(b,arr[k]+ioffset,0);}
1312 } else {
1313 if( newCle )
1314 DOLOOP { newCle->Streamer( arr[k]+ioffset, b, cle ); }
1315 else
1316 DOLOOP { cle->Streamer(arr[k]+ioffset,b);}
1317 }
1318 continue;
1319
1321 TFile *file = (TFile*)b.GetParent();
1322 if (file && file->GetVersion() < 30208) {
1323 // For older ROOT file we use a totally different case to treat
1324 // this situation, so we change 'kase' and restart.
1326 goto SWIT;
1327 }
1328 // there is intentionally no break/continue statement here.
1329 // For newer ROOT file, we always use the generic case for kOffsetL(s)
1330 }
1331
1333 DOLOOP {
1334 b.ReadFastArray((void*)(arr[k]+ioffset),cle,compinfo[i]->fLength,pstreamer);
1335 }
1336 continue;
1337 }
1338
1339 // Base Class
1341 if (!(arrayMode&1)) {
1342 if(pstreamer) {kase = TStreamerInfo::kStreamer; goto SWIT;}
1343 DOLOOP { ((TStreamerBase*)aElement)->ReadBuffer(b,arr[k]);}
1344 } else {
1345 // FIXME: Rather than relying on the StreamerElement to
1346 // contain the base class version information we should
1347 // embed it in the bytestream even in the member-wise case.
1348 // For now rely, on the StreamerElement:
1349 TStreamerInfo *binfo = ((TStreamerInfo*)((TStreamerBase*)aElement)->GetBaseStreamerInfo());
1350 binfo->ReadBuffer(b,arr,binfo->fCompFull,0,binfo->fNfulldata,narr,ioffset,arrayMode);
1351 }
1352 continue;
1353
1357 {
1358 // Backward compatibility. Some TStreamerElement's where without
1359 // Streamer but were not removed from element list
1360 UInt_t start,count;
1361 Version_t v = b.ReadVersion(&start, &count, cle);
1362 if (fOldVersion<3){ // case of old TStreamerInfo
1363 if (count<= 0 || v != fOldVersion) {
1364 b.SetBufferOffset(start);
1365 continue;
1366 }
1367 }
1368 DOLOOP {
1369 b.ReadFastArray((void*)(arr[k]+ioffset),cle,compinfo[i]->fLength,pstreamer);
1370 }
1371 b.CheckByteCount(start,count,aElement->GetFullName());
1372 continue;
1373 }
1374
1375
1377 // Backward compatibility. Some TStreamerElement's where without
1378 // Streamer but were not removed from element list
1379 UInt_t start,count;
1380 Version_t v = b.ReadVersion(&start, &count, cle);
1381 if (fOldVersion<3){ // case of old TStreamerInfo
1382 if (aElement->IsBase() && aElement->IsA()!=TStreamerBase::Class()) {
1383 b.SetBufferOffset(start); //it was no byte count
1384 } else if (kase == TStreamerInfo::kSTL || kase == TStreamerInfo::kSTL+TStreamerInfo::kOffsetL ||
1385 count<= 0 || v != fOldVersion) {
1386 b.SetBufferOffset(start);
1387 continue;
1388 }
1389 }
1390 if (pstreamer == 0) {
1391 Error("ReadBuffer","Streamer for %s is null\n",aElement->GetName());
1392 if (gDebug > 0) {
1393 aElement->ls(); continue;
1394 }
1395 } else {
1396 DOLOOP {(*pstreamer)(b,arr[k]+ioffset,compinfo[i]->fLength);}
1397 }
1398 b.CheckByteCount(start,count,aElement->GetFullName());
1399 }
1400 continue;
1401
1403 // -- A pointer to a varying-length array of objects.
1404 // MyClass* ary; //[n]
1405 // -- Or a pointer to a varying-length array of pointers to objects.
1406 // MyClass** ary; //[n]
1408 // -- An array of pointers to a varying-length array of objects.
1409 // MyClass* ary[d]; //[n]
1410 // -- Or an array of pointers to a varying-length array of pointers to objects.
1411 // MyClass** ary[d]; //[n]
1412 {
1413 // Get the class of the data member.
1414 TClass* cl = compinfo[i]->fClass;
1415 // Which are we, an array of objects or an array of pointers to objects?
1416 Bool_t isPtrPtr = (strstr(aElement->GetTypeName(), "**") != 0);
1417 // Check for a private streamer.
1418 if (pstreamer) {
1419 // -- We have a private streamer.
1420 // Read the class version and byte count from the buffer.
1421 UInt_t start = 0;
1422 UInt_t count = 0;
1423 b.ReadVersion(&start, &count, cl);
1424 // Loop over the entries in the clones array or the STL container.
1425 for (Int_t k = 0; k < narr; ++k) {
1426 Int_t* counter = (Int_t*) (arr[k] /*entry pointer*/ + eoffset /*entry offset*/ + compinfo[i]->fMethod /*counter offset*/);
1427 // And call the private streamer, passing it the buffer, the object, and the counter.
1428 (*pstreamer)(b, arr[k] /*entry pointer*/ + ioffset /*object offset*/, *counter);
1429 }
1430 b.CheckByteCount(start, count, aElement->GetFullName());
1431 // We are done, next streamer element.
1432 continue;
1433 }
1434 // At this point we do *not* have a private streamer.
1435 // Get the version of the file we are reading from.
1436 TFile* file = (TFile*) b.GetParent();
1437 // By default assume the file version is the newest.
1438 Int_t fileVersion = kMaxInt;
1439 if (file) {
1440 fileVersion = file->GetVersion();
1441 }
1442 // Read the class version and byte count from the buffer.
1443 UInt_t start = 0;
1444 UInt_t count = 0;
1445 b.ReadVersion(&start, &count, cl);
1446 if (fileVersion > 51508) {
1447 // -- Newer versions allow polymorphic pointers.
1448 // Loop over the entries in the clones array or the STL container.
1449 for (Int_t k = 0; k < narr; ++k) {
1450 // Get the counter for the varying length array.
1451 Int_t vlen = *((Int_t*) (arr[k] /*entry pointer*/ + eoffset /*entry offset*/ + compinfo[i]->fMethod /*counter offset*/));
1452 //Int_t realLen;
1453 //b >> realLen;
1454 //if (realLen != vlen) {
1455 // fprintf(stderr, "read vlen: %d realLen: %s\n", vlen, realLen);
1456 //}
1457 // Get a pointer to the array of pointers.
1458 char** pp = (char**) (arr[k] /*entry pointer*/ + ioffset /*object offset*/);
1459 if (!pp) {
1460 continue;
1461 }
1462 // Loop over each element of the array of pointers to varying-length arrays.
1463 for (Int_t ndx = 0; ndx < compinfo[i]->fLength; ++ndx) {
1464 //if (!pp[ndx]) {
1465 // -- We do not have a pointer to a varying-length array.
1466 //Error("ReadBuffer", "The pointer to element %s::%s type %d (%s) is null\n", thisVar->GetName(), aElement->GetFullName(), compinfo[i]->fType, aElement->GetTypeName());
1467 //continue;
1468 //}
1469 // Delete any memory at pp[ndx].
1470 if (!isPtrPtr) {
1471 cl->DeleteArray(pp[ndx]);
1472 pp[ndx] = 0;
1473 } else {
1474 // Using vlen is wrong here because it has already
1475 // been overwritten with the value needed to read
1476 // the current record. Fixing this will require
1477 // doing a pass over the object at the beginning
1478 // of the I/O and releasing all the buffer memory
1479 // for varying length arrays before we overwrite
1480 // the counter values.
1481 //
1482 // For now we will just leak memory, just as we
1483 // have always done in the past. Fix this.
1484 //
1485 //char** r = (char**) pp[ndx];
1486 //if (r) {
1487 // for (Int_t v = 0; v < vlen; ++v) {
1488 // cl->Destructor(r[v]);
1489 // r[v] = 0;
1490 // }
1491 //}
1492 delete[] pp[ndx];
1493 pp[ndx] = 0;
1494 }
1495 if (!vlen) {
1496 continue;
1497 }
1498 // Note: We now have pp[ndx] is null.
1499 // Allocate memory to read into.
1500 if (!isPtrPtr) {
1501 // -- We are a varying-length array of objects.
1502 // Note: Polymorphism is not allowed here.
1503 // Allocate a new array of objects to read into.
1504 pp[ndx] = (char*) cl->NewArray(vlen);
1505 if (!pp[ndx]) {
1506 Error("ReadBuffer", "Memory allocation failed!\n");
1507 continue;
1508 }
1509 } else {
1510 // -- We are a varying-length array of pointers to objects.
1511 // Note: The object pointers are allowed to be polymorphic.
1512 // Allocate a new array of pointers to objects to read into.
1513 pp[ndx] = (char*) new char*[vlen];
1514 if (!pp[ndx]) {
1515 Error("ReadBuffer", "Memory allocation failed!\n");
1516 continue;
1517 }
1518 // And set each pointer to null.
1519 memset(pp[ndx], 0, vlen * sizeof(char*)); // This is the right size we really have a char**: pp[ndx] = (char*) new char*[vlen];
1520 }
1521 if (!isPtrPtr) {
1522 // -- We are a varying-length array of objects.
1523 b.ReadFastArray(pp[ndx], cl, vlen, 0);
1524 }
1525 else {
1526 // -- We are a varying-length array of object pointers.
1527 b.ReadFastArray((void**) pp[ndx], cl, vlen, kFALSE, 0);
1528 } // isPtrPtr
1529 } // ndx
1530 } // k
1531 }
1532 else {
1533 // -- Older versions do *not* allow polymorphic pointers.
1534 // Loop over the entries in the clones array or the STL container.
1535 for (Int_t k = 0; k < narr; ++k) {
1536 // Get the counter for the varying length array.
1537 Int_t vlen = *((Int_t*) (arr[k] /*entry pointer*/ + eoffset /*entry offset*/ + compinfo[i]->fMethod /*counter offset*/));
1538 //Int_t realLen;
1539 //b >> realLen;
1540 //if (realLen != vlen) {
1541 // fprintf(stderr, "read vlen: %d realLen: %s\n", vlen, realLen);
1542 //}
1543 // Get a pointer to the array of pointers.
1544 char** pp = (char**) (arr[k] /*entry pointer*/ + ioffset /*object offset*/);
1545 if (!pp) {
1546 continue;
1547 }
1548 // Loop over each element of the array of pointers to varying-length arrays.
1549 for (Int_t ndx = 0; ndx < compinfo[i]->fLength; ++ndx) {
1550 //if (!pp[ndx]) {
1551 // -- We do not have a pointer to a varying-length array.
1552 //Error("ReadBuffer", "The pointer to element %s::%s type %d (%s) is null\n", thisVar->GetName(), aElement->GetFullName(), compinfo[i]->fType, aElement->GetTypeName());
1553 //continue;
1554 //}
1555 // Delete any memory at pp[ndx].
1556 if (!isPtrPtr) {
1557 cl->DeleteArray(pp[ndx]);
1558 pp[ndx] = 0;
1559 } else {
1560 // Using vlen is wrong here because it has already
1561 // been overwritten with the value needed to read
1562 // the current record. Fixing this will require
1563 // doing a pass over the object at the beginning
1564 // of the I/O and releasing all the buffer memory
1565 // for varying length arrays before we overwrite
1566 // the counter values.
1567 //
1568 // For now we will just leak memory, just as we
1569 // have always done in the past. Fix this.
1570 //
1571 //char** r = (char**) pp[ndx];
1572 //if (r) {
1573 // for (Int_t v = 0; v < vlen; ++v) {
1574 // cl->Destructor(r[v]);
1575 // r[v] = 0;
1576 // }
1577 //}
1578 delete[] pp[ndx];
1579 pp[ndx] = 0;
1580 }
1581 if (!vlen) {
1582 continue;
1583 }
1584 // Note: We now have pp[ndx] is null.
1585 // Allocate memory to read into.
1586 if (!isPtrPtr) {
1587 // -- We are a varying-length array of objects.
1588 // Note: Polymorphism is not allowed here.
1589 // Allocate a new array of objects to read into.
1590 pp[ndx] = (char*) cl->NewArray(vlen);
1591 if (!pp[ndx]) {
1592 Error("ReadBuffer", "Memory allocation failed!\n");
1593 continue;
1594 }
1595 } else {
1596 // -- We are a varying-length array of pointers to objects.
1597 // Note: The object pointers are allowed to be polymorphic.
1598 // Allocate a new array of pointers to objects to read into.
1599 pp[ndx] = (char*) new char*[vlen];
1600 if (!pp[ndx]) {
1601 Error("ReadBuffer", "Memory allocation failed!\n");
1602 continue;
1603 }
1604 // And set each pointer to null.
1605 memset(pp[ndx], 0, vlen * sizeof(char*)); // This is the right size we really have a char**: pp[ndx] = (char*) new char*[vlen];
1606 }
1607 if (!isPtrPtr) {
1608 // -- We are a varying-length array of objects.
1609 // Loop over the elements of the varying length array.
1610 for (Int_t v = 0; v < vlen; ++v) {
1611 // Read the object from the buffer.
1612 cl->Streamer(pp[ndx] + (v * cl->Size()), b);
1613 } // v
1614 }
1615 else {
1616 // -- We are a varying-length array of object pointers.
1617 // Get a pointer to the object pointer array.
1618 char** r = (char**) pp[ndx];
1619 // Loop over the elements of the varying length array.
1620 for (Int_t v = 0; v < vlen; ++v) {
1621 // Allocate an object to read into.
1622 r[v] = (char*) cl->New();
1623 if (!r[v]) {
1624 // Do not print a second error message here.
1625 //Error("ReadBuffer", "Memory allocation failed!\n");
1626 continue;
1627 }
1628 // Read the object from the buffer.
1629 cl->Streamer(r[v], b);
1630 } // v
1631 } // isPtrPtr
1632 } // ndx
1633 } // k
1634 } // fileVersion
1635 b.CheckByteCount(start, count, aElement->GetFullName());
1636 continue;
1637 }
1638
1640 ((TBufferFile&)b).PushDataCache( new TVirtualArray( aElement->GetClassPointer(), narr ) );
1641 continue;
1643 delete ((TBufferFile&)b).PopDataCache();
1644 continue;
1645
1646 case -1:
1647 // -- Skip an ignored TObject base class.
1648 continue;
1649
1650 default: {
1651 int ans = -1;
1652
1653 if (TStreamerInfo::kCache <= kase && kase < TStreamerInfo::kArtificial) {
1654
1655 //T &cache_add = *(T*)b.PeekDataCacheArray();
1656 R__ASSERT(kFALSE); // cache_add);
1657
1658 // thisVar->ReadBuffer(b,cache_addr,i,kase-TStreamerInfo::kCache,aElement,narr,eoffset)
1659
1660 continue;
1661 }
1662
1663 if (kase >= TStreamerInfo::kConv)
1664 ans = thisVar->ReadBufferConv(b,arr,compinfo[i],kase,aElement,narr,eoffset);
1665 if (ans==0) continue;
1666
1667 if (kase >= TStreamerInfo::kSkip)
1668 ans = thisVar->ReadBufferSkip(b,arr,compinfo[i],kase,aElement,narr,eoffset);
1669 if (ans==0) continue;
1670
1671 if (kase >= TStreamerInfo::kArtificial) {
1672 ans = thisVar->ReadBufferArtificial(b,arr,aElement,narr,eoffset);
1673 }
1674 if (ans==0) continue;
1675 }
1676 if (aElement)
1677 Error("ReadBuffer","The element %s::%s type %d (%s) is not supported yet\n",
1678 thisVar->GetName(),aElement->GetFullName(),kase,aElement->GetTypeName());
1679 else
1680 Error("ReadBuffer","The TStreamerElement for %s %d is missing!\n",
1681 thisVar->GetName(),i);
1682
1683 continue;
1684 }
1685 }
1686 if (needIncrement) b.DecrementLevel(thisVar);
1687 return 0;
1688}
1689
1690template Int_t TStreamerInfo::ReadBufferSkip<char**>(TBuffer &b, char** const &arr, const TCompInfo *compinfo, Int_t kase,
1691 TStreamerElement *aElement, Int_t narr,
1692 Int_t eoffset);
1693template Int_t TStreamerInfo::ReadBufferSkip<TVirtualCollectionProxy>(TBuffer &b, const TVirtualCollectionProxy &arr, const TCompInfo *compinfo, Int_t kase,
1694 TStreamerElement *aElement, Int_t narr,
1695 Int_t eoffset);
1696template Int_t TStreamerInfo::ReadBufferSkip<TVirtualArray>(TBuffer &b, const TVirtualArray &arr, const TCompInfo *compinfo, Int_t kase,
1697 TStreamerElement *aElement, Int_t narr,
1698 Int_t eoffset);
1699
1700template Int_t TStreamerInfo::ReadBufferConv<char**>(TBuffer &b, char** const &arr, const TCompInfo *compinfo, Int_t kase,
1701 TStreamerElement *aElement, Int_t narr,
1702 Int_t eoffset);
1703template Int_t TStreamerInfo::ReadBufferConv<TVirtualCollectionProxy>(TBuffer &b, const TVirtualCollectionProxy &arr, const TCompInfo *compinfo, Int_t kase,
1704 TStreamerElement *aElement, Int_t narr,
1705 Int_t eoffset);
1706template Int_t TStreamerInfo::ReadBufferConv<TVirtualArray>(TBuffer &b, const TVirtualArray &arr, const TCompInfo *compinfo, Int_t kase,
1707 TStreamerElement *aElement, Int_t narr,
1708 Int_t eoffset);
1709
1710template Int_t TStreamerInfo::ReadBufferArtificial<char**>(TBuffer &b, char** const &arr,
1711 TStreamerElement *aElement, Int_t narr,
1712 Int_t eoffset);
1713template Int_t TStreamerInfo::ReadBufferArtificial<TVirtualCollectionProxy>(TBuffer &b, const TVirtualCollectionProxy &arr,
1714 TStreamerElement *aElement, Int_t narr,
1715 Int_t eoffset);
1716template Int_t TStreamerInfo::ReadBufferArtificial<TVirtualArray>(TBuffer &b, const TVirtualArray &arr,
1717 TStreamerElement *aElement, Int_t narr,
1718 Int_t eoffset);
1719
1720template Int_t TStreamerInfo::ReadBuffer<char**>(TBuffer &b, char** const &arr,
1721 TCompInfo *const*const compinfo, Int_t first, Int_t last,
1722 Int_t narr, Int_t eoffset, Int_t arrayMode);
1723template Int_t TStreamerInfo::ReadBuffer<TVirtualCollectionProxy>(TBuffer &b, const TVirtualCollectionProxy &arr,
1724 TCompInfo *const*const compinfo, Int_t first, Int_t last,
1725 Int_t narr, Int_t eoffset, Int_t arrayMode);
1726template Int_t TStreamerInfo::ReadBuffer<TVirtualArray>(TBuffer &b, const TVirtualArray &arr,
1727 TCompInfo *const*const compinfo, Int_t first, Int_t last,
1728 Int_t narr, Int_t eoffset, Int_t arrayMode);
1729
1730////////////////////////////////////////////////////////////////////////////////
1731/// The STL vector/list is deserialized from the buffer b
1732
1734 Int_t nc, Int_t eoffset, Bool_t v7 /* = kTRUE */)
1735{
1736 if (!nc && v7) return 0; // in version 6 of TStreamerInfo and below, we were calling ReadBuffer for empty collection.
1737 int ret = ReadBuffer(b, *cont,fCompFull,0,fNfulldata,nc,eoffset,1);
1738 return ret;
1739}
1740
1741////////////////////////////////////////////////////////////////////////////////
1742/// Read for TClonesArray.
1743/// Note: This is no longer used.
1744
1746 Int_t nc, Int_t first, Int_t eoffset)
1747{
1748 char **arr = (char **)clones->GetObjectRef(0);
1749 return ReadBuffer(b,arr,fCompFull,first==-1?0:first,first==-1?fNfulldata:first+1,nc,eoffset,1);
1750}
ROOT::R::TRInterface & r
Definition Object.C:4
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
unsigned short UShort_t
Definition RtypesCore.h:40
double Double32_t
Definition RtypesCore.h:60
int Int_t
Definition RtypesCore.h:45
const Int_t kMaxInt
Definition RtypesCore.h:112
short Version_t
Definition RtypesCore.h:65
unsigned char UChar_t
Definition RtypesCore.h:38
char Char_t
Definition RtypesCore.h:37
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:101
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
bool Bool_t
Definition RtypesCore.h:63
short Short_t
Definition RtypesCore.h:39
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:80
unsigned long long ULong64_t
Definition RtypesCore.h:81
float Float_t
Definition RtypesCore.h:57
#define DOLOOP(x)
#define R__ASSERT(e)
Definition TError.h:118
Int_t gDebug
Definition TROOT.cxx:592
#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: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:5179
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:4964
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:5915
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5690
void DeleteArray(void *ary, Bool_t dtorOnly=kFALSE)
Explicitly call operator delete[] for an array.
Definition TClass.cxx:5515
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:4585
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2895
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:7072
@ kEmulated
Definition TClass.h:125
An array of clone (identical) objects.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
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:63
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:201
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:447
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:200
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:777
@ 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
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.
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...
@ 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:136
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
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...
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
Definition file.py:1
Definition first.py:1
auto * l
Definition textangle.C:4