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