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