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