Logo ROOT  
Reference Guide
TBufferFile.cxx
Go to the documentation of this file.
1 // @(#)root/io:$Id$
2 // Author: Rene Brun 17/01/2007
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2007, 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 /**
13 \file TBufferFile.cxx
14 \class TBufferFile
15 \ingroup IO
16 
17 The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
18 */
19 
20 #include <string.h>
21 #include <typeinfo>
22 #include <string>
23 
24 #include "TFile.h"
25 #include "TBufferFile.h"
26 #include "TExMap.h"
27 #include "TClass.h"
28 #include "TStorage.h"
29 #include "TError.h"
30 #include "TStreamer.h"
31 #include "TStreamerInfo.h"
32 #include "TStreamerElement.h"
33 #include "TSchemaRuleSet.h"
34 #include "TStreamerInfoActions.h"
35 #include "TInterpreter.h"
36 #include "TVirtualMutex.h"
37 
38 #if (defined(__linux) || defined(__APPLE__)) && defined(__i386__) && \
39  defined(__GNUC__)
40 #define USE_BSWAPCPY
41 #endif
42 
43 #ifdef USE_BSWAPCPY
44 #include "Bswapcpy.h"
45 #endif
46 
47 
48 const UInt_t kNewClassTag = 0xFFFFFFFF;
49 const UInt_t kClassMask = 0x80000000; // OR the class index with this
50 const UInt_t kByteCountMask = 0x40000000; // OR the byte count with this
51 const UInt_t kMaxMapCount = 0x3FFFFFFE; // last valid fMapCount and byte count
52 const Version_t kByteCountVMask = 0x4000; // OR the version byte count with this
53 const Version_t kMaxVersion = 0x3FFF; // highest possible version number
54 const Int_t kMapOffset = 2; // first 2 map entries are taken by null obj and self obj
55 
56 
58 
59 ////////////////////////////////////////////////////////////////////////////////
60 /// Thread-safe check on StreamerInfos of a TClass
61 
62 static inline bool Class_Has_StreamerInfo(const TClass* cl)
63 {
64  // NOTE: we do not need a R__LOCKGUARD2 since we know the
65  // mutex is available since the TClass constructor will make
66  // it
68  return cl->GetStreamerInfos()->GetLast()>1;
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Create an I/O buffer object. Mode should be either TBuffer::kRead or
73 /// TBuffer::kWrite. By default the I/O buffer has a size of
74 /// TBuffer::kInitialSize (1024) bytes.
75 
77  :TBufferIO(mode),
78  fInfo(nullptr), fInfoStack()
79 {
80 }
81 
82 ////////////////////////////////////////////////////////////////////////////////
83 /// Create an I/O buffer object. Mode should be either TBuffer::kRead or
84 /// TBuffer::kWrite.
85 
87  :TBufferIO(mode,bufsiz),
88  fInfo(nullptr), fInfoStack()
89 {
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 /// Create an I/O buffer object.
94 /// Mode should be either TBuffer::kRead or
95 /// TBuffer::kWrite. By default the I/O buffer has a size of
96 /// TBuffer::kInitialSize (1024) bytes. An external buffer can be passed
97 /// to TBuffer via the buf argument. By default this buffer will be adopted
98 /// unless adopt is false.
99 /// If the new buffer is <b>not</b> adopted and no memory allocation routine
100 /// is provided, a Fatal error will be issued if the Buffer attempts to
101 /// expand.
102 
103 TBufferFile::TBufferFile(TBuffer::EMode mode, Int_t bufsiz, void *buf, Bool_t adopt, ReAllocCharFun_t reallocfunc) :
104  TBufferIO(mode,bufsiz,buf,adopt,reallocfunc),
105  fInfo(nullptr), fInfoStack()
106 {
107 }
108 
109 ////////////////////////////////////////////////////////////////////////////////
110 /// Delete an I/O buffer object.
111 
113 {
114 }
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 /// Increment level.
118 
120 {
121  fInfoStack.push_back(fInfo);
122  fInfo = (TStreamerInfo*)info;
123 }
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 /// Decrement level.
127 
129 {
130  fInfo = fInfoStack.back();
131  fInfoStack.pop_back();
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// Handle old file formats.
136 ///
137 /// Files written with versions older than 3.00/06 had a non-portable
138 /// implementation of Long_t/ULong_t. These types should not have been
139 /// used at all. However, because some users had already written many
140 /// files with these types we provide this dirty patch for "backward
141 /// compatibility"
142 
143 static void frombufOld(char *&buf, Long_t *x)
144 {
145 #ifdef R__BYTESWAP
146 #ifdef R__B64
147  char *sw = (char *)x;
148  sw[0] = buf[7];
149  sw[1] = buf[6];
150  sw[2] = buf[5];
151  sw[3] = buf[4];
152  sw[4] = buf[3];
153  sw[5] = buf[2];
154  sw[6] = buf[1];
155  sw[7] = buf[0];
156 #else
157  char *sw = (char *)x;
158  sw[0] = buf[3];
159  sw[1] = buf[2];
160  sw[2] = buf[1];
161  sw[3] = buf[0];
162 #endif
163 #else
164  memcpy(x, buf, sizeof(Long_t));
165 #endif
166  buf += sizeof(Long_t);
167 }
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 /// Read Long from TBuffer.
171 
173 {
174  TFile *file = (TFile*)fParent;
175  if (file && file->GetVersion() < 30006) {
176  frombufOld(fBufCur, &l);
177  } else {
178  frombuf(fBufCur, &l);
179  }
180 }
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 /// Read TString from TBuffer.
184 
186 {
187  Int_t nbig;
188  UChar_t nwh;
189  *this >> nwh;
190  if (nwh == 0) {
191  s.UnLink();
192  s.Zero();
193  } else {
194  if (nwh == 255)
195  *this >> nbig;
196  else
197  nbig = nwh;
198 
199  s.Clobber(nbig);
200  char *data = s.GetPointer();
201  data[nbig] = 0;
202  s.SetSize(nbig);
203  ReadFastArray(data, nbig);
204  }
205 }
206 
207 ////////////////////////////////////////////////////////////////////////////////
208 /// Write TString to TBuffer.
209 
211 {
212  Int_t nbig = s.Length();
213  UChar_t nwh;
214  if (nbig > 254) {
215  nwh = 255;
216  *this << nwh;
217  *this << nbig;
218  } else {
219  nwh = UChar_t(nbig);
220  *this << nwh;
221  }
222  const char *data = s.GetPointer();
223  WriteFastArray(data, nbig);
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Read std::string from TBuffer.
228 
229 void TBufferFile::ReadStdString(std::string *obj)
230 {
231  if (obj == nullptr) {
232  Error("TBufferFile::ReadStdString","The std::string address is nullptr but should not");
233  return;
234  }
235  Int_t nbig;
236  UChar_t nwh;
237  *this >> nwh;
238  if (nwh == 0) {
239  obj->clear();
240  } else {
241  if( obj->size() ) {
242  // Insure that the underlying data storage is not shared
243  (*obj)[0] = '\0';
244  }
245  if (nwh == 255) {
246  *this >> nbig;
247  obj->resize(nbig,'\0');
248  ReadFastArray((char*)obj->data(),nbig);
249  }
250  else {
251  obj->resize(nwh,'\0');
252  ReadFastArray((char*)obj->data(),nwh);
253  }
254  }
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Write std::string to TBuffer.
259 
260 void TBufferFile::WriteStdString(const std::string *obj)
261 {
262  if (obj==0) {
263  *this << (UChar_t)0;
264  WriteFastArray("",0);
265  return;
266  }
267 
268  UChar_t nwh;
269  Int_t nbig = obj->length();
270  if (nbig > 254) {
271  nwh = 255;
272  *this << nwh;
273  *this << nbig;
274  } else {
275  nwh = UChar_t(nbig);
276  *this << nwh;
277  }
278  WriteFastArray(obj->data(),nbig);
279 }
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 /// Read char* from TBuffer.
283 
285 {
286  delete [] s;
287  s = nullptr;
288 
289  Int_t nch;
290  *this >> nch;
291  if (nch > 0) {
292  s = new char[nch+1];
293  ReadFastArray(s, nch);
294  s[nch] = 0;
295  }
296 }
297 
298 ////////////////////////////////////////////////////////////////////////////////
299 /// Write char* into TBuffer.
300 
302 {
303  Int_t nch = 0;
304  if (s) {
305  nch = strlen(s);
306  *this << nch;
307  WriteFastArray(s,nch);
308  } else {
309  *this << nch;
310  }
311 
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// Set byte count at position cntpos in the buffer. Generate warning if
316 /// count larger than kMaxMapCount. The count is excluded its own size.
317 
318 void TBufferFile::SetByteCount(UInt_t cntpos, Bool_t packInVersion)
319 {
320  UInt_t cnt = UInt_t(fBufCur - fBuffer) - cntpos - sizeof(UInt_t);
321  char *buf = (char *)(fBuffer + cntpos);
322 
323  // if true, pack byte count in two consecutive shorts, so it can
324  // be read by ReadVersion()
325  if (packInVersion) {
326  union {
327  UInt_t cnt;
328  Version_t vers[2];
329  } v;
330  v.cnt = cnt;
331 #ifdef R__BYTESWAP
332  tobuf(buf, Version_t(v.vers[1] | kByteCountVMask));
333  tobuf(buf, v.vers[0]);
334 #else
335  tobuf(buf, Version_t(v.vers[0] | kByteCountVMask));
336  tobuf(buf, v.vers[1]);
337 #endif
338  } else
339  tobuf(buf, cnt | kByteCountMask);
340 
341  if (cnt >= kMaxMapCount) {
342  Error("WriteByteCount", "bytecount too large (more than %d)", kMaxMapCount);
343  // exception
344  }
345 }
346 
347 ////////////////////////////////////////////////////////////////////////////////
348 /// Check byte count with current buffer position. They should
349 /// match. If not print warning and position buffer in correct
350 /// place determined by the byte count. Startpos is position of
351 /// first byte where the byte count is written in buffer.
352 /// Returns 0 if everything is ok, otherwise the bytecount offset
353 /// (< 0 when read too little, >0 when read too much).
354 
355 Int_t TBufferFile::CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss, const char *classname)
356 {
357  if (!bcnt) return 0;
358 
359  Int_t offset = 0;
360 
361  Long_t endpos = Long_t(fBuffer) + startpos + bcnt + sizeof(UInt_t);
362 
363  if (Long_t(fBufCur) != endpos) {
364  offset = Int_t(Long_t(fBufCur) - endpos);
365 
366  const char *name = clss ? clss->GetName() : classname ? classname : 0;
367 
368  if (name) {
369  if (offset < 0) {
370  Error("CheckByteCount", "object of class %s read too few bytes: %d instead of %d",
371  name,bcnt+offset,bcnt);
372  }
373  if (offset > 0) {
374  Error("CheckByteCount", "object of class %s read too many bytes: %d instead of %d",
375  name,bcnt+offset,bcnt);
376  if (fParent)
377  Warning("CheckByteCount","%s::Streamer() not in sync with data on file %s, fix Streamer()",
378  name, fParent->GetName());
379  else
380  Warning("CheckByteCount","%s::Streamer() not in sync with data, fix Streamer()",
381  name);
382  }
383  }
384  if ( ((char *)endpos) > fBufMax ) {
385  offset = fBufMax-fBufCur;
386  Error("CheckByteCount",
387  "Byte count probably corrupted around buffer position %d:\n\t%d for a possible maximum of %d",
388  startpos, bcnt, offset);
389  fBufCur = fBufMax;
390 
391  } else {
392 
393  fBufCur = (char *) endpos;
394 
395  }
396  }
397  return offset;
398 }
399 
400 ////////////////////////////////////////////////////////////////////////////////
401 /// Check byte count with current buffer position. They should
402 /// match. If not print warning and position buffer in correct
403 /// place determined by the byte count. Startpos is position of
404 /// first byte where the byte count is written in buffer.
405 /// Returns 0 if everything is ok, otherwise the bytecount offset
406 /// (< 0 when read too little, >0 when read too much).
407 
409 {
410  if (!bcnt) return 0;
411  return CheckByteCount( startpos, bcnt, clss, nullptr);
412 }
413 
414 ////////////////////////////////////////////////////////////////////////////////
415 /// Check byte count with current buffer position. They should
416 /// match. If not print warning and position buffer in correct
417 /// place determined by the byte count. Startpos is position of
418 /// first byte where the byte count is written in buffer.
419 /// Returns 0 if everything is ok, otherwise the bytecount offset
420 /// (< 0 when read too little, >0 when read too much).
421 
422 Int_t TBufferFile::CheckByteCount(UInt_t startpos, UInt_t bcnt, const char *classname)
423 {
424  if (!bcnt) return 0;
425  return CheckByteCount( startpos, bcnt, nullptr, classname);
426 }
427 
428 ////////////////////////////////////////////////////////////////////////////////
429 /// Read a Float16_t from the buffer,
430 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16().
431 
433 {
434  if (ele && ele->GetFactor() != 0) {
435  ReadWithFactor(f, ele->GetFactor(), ele->GetXmin());
436  } else {
437  Int_t nbits = 0;
438  if (ele) nbits = (Int_t)ele->GetXmin();
439  if (!nbits) nbits = 12;
440  ReadWithNbits(f, nbits);
441  }
442 }
443 
444 ////////////////////////////////////////////////////////////////////////////////
445 /// Read a Double32_t from the buffer,
446 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
447 
449 {
450  if (ele && ele->GetFactor() != 0) {
451  ReadWithFactor(d, ele->GetFactor(), ele->GetXmin());
452  } else {
453  Int_t nbits = 0;
454  if (ele) nbits = (Int_t)ele->GetXmin();
455  if (!nbits) {
456  //we read a float and convert it to double
457  Float_t afloat;
458  *this >> afloat;
459  d[0] = (Double_t)afloat;
460  } else {
461  ReadWithNbits(d, nbits);
462  }
463  }
464 }
465 
466 ////////////////////////////////////////////////////////////////////////////////
467 /// Read a Float16_t from the buffer when the factor and minimum value have been specified
468 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
469 
471 {
472  //a range was specified. We read an integer and convert it back to a double.
473  UInt_t aint;
474  frombuf(this->fBufCur,&aint);
475  ptr[0] = (Float_t)(aint/factor + minvalue);
476 }
477 
478 ////////////////////////////////////////////////////////////////////////////////
479 /// Read a Float16_t from the buffer when the number of bits is specified (explicitly or not)
480 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16().
481 
483 {
484  //we read the exponent and the truncated mantissa of the float
485  //and rebuild the float.
486  union {
487  Float_t fFloatValue;
488  Int_t fIntValue;
489  } temp;
490  UChar_t theExp;
491  UShort_t theMan;
492  frombuf(this->fBufCur,&theExp);
493  frombuf(this->fBufCur,&theMan);
494  temp.fIntValue = theExp;
495  temp.fIntValue <<= 23;
496  temp.fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
497  if(1<<(nbits+1) & theMan) temp.fFloatValue = -temp.fFloatValue;
498  ptr[0] = temp.fFloatValue;
499 }
500 
501 ////////////////////////////////////////////////////////////////////////////////
502 /// Read a Double32_t from the buffer when the factor and minimum value have been specified
503 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
504 
506 {
507  //a range was specified. We read an integer and convert it back to a double.
508  UInt_t aint;
509  frombuf(this->fBufCur,&aint);
510  ptr[0] = (Double_t)(aint/factor + minvalue);
511 }
512 
513 ////////////////////////////////////////////////////////////////////////////////
514 /// Read a Double32_t from the buffer when the number of bits is specified (explicitly or not)
515 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32().
516 
518 {
519  //we read the exponent and the truncated mantissa of the float
520  //and rebuild the float.
521  union {
522  Float_t fFloatValue;
523  Int_t fIntValue;
524  } temp;
525  UChar_t theExp;
526  UShort_t theMan;
527  frombuf(this->fBufCur,&theExp);
528  frombuf(this->fBufCur,&theMan);
529  temp.fIntValue = theExp;
530  temp.fIntValue <<= 23;
531  temp.fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
532  if(1<<(nbits+1) & theMan) temp.fFloatValue = -temp.fFloatValue;
533  ptr[0] = (Double_t)temp.fFloatValue;
534 }
535 
536 ////////////////////////////////////////////////////////////////////////////////
537 /// Write a Float16_t to the buffer.
538 ///
539 /// The following cases are supported for streaming a Float16_t type
540 /// depending on the range declaration in the comment field of the data member:
541 /// Case | Example |
542 /// -----|---------|
543 /// A | Float16_t fNormal; |
544 /// B | Float16_t fTemperature; //[0,100]|
545 /// C | Float16_t fCharge; //[-1,1,2]|
546 /// D | Float16_t fVertex[3]; //[-30,30,10]|
547 /// E | Float16_t fChi2; //[0,0,6]|
548 /// F | Int_t fNsp;<br>Float16_t* fPointValue; //[fNsp][0,3]|
549 ///
550 /// - In case A fNormal is converted from a Float_t to a Float_t with mantissa truncated to 12 bits
551 /// - In case B fTemperature is converted to a 32 bit unsigned integer
552 /// - In case C fCharge is converted to a 2 bits unsigned integer
553 /// - In case D the array elements of fVertex are converted to an unsigned 10 bits integer
554 /// - In case E fChi2 is converted to a Float_t with truncated precision at 6 bits
555 /// - In case F the fNsp elements of array fPointvalue are converted to an unsigned 32 bit integer
556 /// Note that the range specifier must follow the dimension specifier.
557 /// Case B has more precision (9 to 10 significative digits than case A (6 to 7 digits).
558 ///
559 /// The range specifier has the general format: [xmin,xmax] or [xmin,xmax,nbits]
560 /// - [0,1];
561 /// - [-10,100];
562 /// - [-pi,pi], [-pi/2,pi/4],[-2pi,2*pi]
563 /// - [-10,100,16]
564 /// - [0,0,8]
565 /// if nbits is not specified, or nbits <2 or nbits>16 it is set to 16. If
566 /// (xmin==0 and xmax==0 and nbits <=14) the float word will have
567 /// its mantissa truncated to nbits significative bits.
568 ///
569 /// ## IMPORTANT NOTE
570 /// ### NOTE 1
571 /// Lets assume an original variable float x:
572 /// When using the format [0,0,8] (ie range not specified) you get the best
573 /// relative precision when storing and reading back the truncated x, say xt.
574 /// The variance of (x-xt)/x will be better than when specifying a range
575 /// for the same number of bits. However the precision relative to the
576 /// range (x-xt)/(xmax-xmin) will be worst, and vice-versa.
577 /// The format [0,0,8] is also interesting when the range of x is infinite
578 /// or unknown.
579 ///
580 /// ### NOTE 2
581 /// It is important to understand the difference with the meaning of nbits
582 /// - in case of [-1,1,nbits], nbits is the total number of bits used to make
583 /// the conversion from a float to an integer
584 /// - in case of [0,0,nbits], nbits is the number of bits used for the mantissa
585 ///
586 /// See example of use of the Float16_t data type in tutorial double32.C
587 /// \image html tbufferfile_double32.gif
588 
590 {
591 
592  if (ele && ele->GetFactor() != 0) {
593  //A range is specified. We normalize the double to the range and
594  //convert it to an integer using a scaling factor that is a function of nbits.
595  //see TStreamerElement::GetRange.
596  Double_t x = f[0];
597  Double_t xmin = ele->GetXmin();
598  Double_t xmax = ele->GetXmax();
599  if (x < xmin) x = xmin;
600  if (x > xmax) x = xmax;
601  UInt_t aint = UInt_t(0.5+ele->GetFactor()*(x-xmin)); *this << aint;
602  } else {
603  Int_t nbits = 0;
604  //number of bits stored in fXmin (see TStreamerElement::GetRange)
605  if (ele) nbits = (Int_t)ele->GetXmin();
606  if (!nbits) nbits = 12;
607  //a range is not specified, but nbits is.
608  //In this case we truncate the mantissa to nbits and we stream
609  //the exponent as a UChar_t and the mantissa as a UShort_t.
610  union {
611  Float_t fFloatValue;
612  Int_t fIntValue;
613  };
614  fFloatValue = f[0];
615  UChar_t theExp = (UChar_t)(0x000000ff & ((fIntValue<<1)>>24));
616  UShort_t theMan = ((1<<(nbits+1))-1) & (fIntValue>>(23-nbits-1));
617  theMan++;
618  theMan = theMan>>1;
619  if (theMan&1<<nbits) theMan = (1<<nbits) - 1;
620  if (fFloatValue < 0) theMan |= 1<<(nbits+1);
621  *this << theExp;
622  *this << theMan;
623  }
624 }
625 
626 ////////////////////////////////////////////////////////////////////////////////
627 /// Write a Double32_t to the buffer.
628 ///
629 /// The following cases are supported for streaming a Double32_t type
630 /// depending on the range declaration in the comment field of the data member:
631 /// Case | Example |
632 /// -----|---------|
633 /// A | Double32_t fNormal; |
634 /// B | Double32_t fTemperature; //[0,100]|
635 /// C | Double32_t fCharge; //[-1,1,2]|
636 /// D | Double32_t fVertex[3]; //[-30,30,10]|
637 /// E | Double32_t fChi2; //[0,0,6]|
638 /// F | Int_t fNsp;<br>Double32_t* fPointValue; //[fNsp][0,3]|
639 ///
640 /// In case A fNormal is converted from a Double_t to a Float_t
641 /// In case B fTemperature is converted to a 32 bit unsigned integer
642 /// In case C fCharge is converted to a 2 bits unsigned integer
643 /// In case D the array elements of fVertex are converted to an unsigned 10 bits integer
644 /// In case E fChi2 is converted to a Float_t with mantissa truncated precision at 6 bits
645 /// In case F the fNsp elements of array fPointvalue are converted to an unsigned 32 bit integer
646 /// Note that the range specifier must follow the dimension specifier.
647 /// Case B has more precision (9 to 10 significative digits than case A (6 to 7 digits).
648 /// See TBufferFile::WriteFloat16 for more information.
649 ///
650 /// see example of use of the Double32_t data type in tutorial double32.C
651 /// \image html tbufferfile_double32.gif
652 
654 {
655 
656  if (ele && ele->GetFactor() != 0) {
657  //A range is specified. We normalize the double to the range and
658  //convert it to an integer using a scaling factor that is a function of nbits.
659  //see TStreamerElement::GetRange.
660  Double_t x = d[0];
661  Double_t xmin = ele->GetXmin();
662  Double_t xmax = ele->GetXmax();
663  if (x < xmin) x = xmin;
664  if (x > xmax) x = xmax;
665  UInt_t aint = UInt_t(0.5+ele->GetFactor()*(x-xmin)); *this << aint;
666  } else {
667  Int_t nbits = 0;
668  //number of bits stored in fXmin (see TStreamerElement::GetRange)
669  if (ele) nbits = (Int_t)ele->GetXmin();
670  if (!nbits) {
671  //if no range and no bits specified, we convert from double to float
672  Float_t afloat = (Float_t)d[0];
673  *this << afloat;
674  } else {
675  //a range is not specified, but nbits is.
676  //In this case we truncate the mantissa to nbits and we stream
677  //the exponent as a UChar_t and the mantissa as a UShort_t.
678  union {
679  Float_t fFloatValue;
680  Int_t fIntValue;
681  };
682  fFloatValue = (Float_t)d[0];
683  UChar_t theExp = (UChar_t)(0x000000ff & ((fIntValue<<1)>>24));
684  UShort_t theMan = ((1<<(nbits+1))-1) & (fIntValue>>(23-nbits-1)) ;
685  theMan++;
686  theMan = theMan>>1;
687  if (theMan&1<<nbits) theMan = (1<<nbits)-1 ;
688  if (fFloatValue < 0) theMan |= 1<<(nbits+1);
689  *this << theExp;
690  *this << theMan;
691  }
692  }
693 }
694 
695 ////////////////////////////////////////////////////////////////////////////////
696 /// Read array of bools from the I/O buffer. Returns the number of
697 /// bools read. If argument is a 0 pointer then space will be
698 /// allocated for the array.
699 
701 {
702  R__ASSERT(IsReading());
703 
704  Int_t n;
705  *this >> n;
706 
707  if (n <= 0 || n > fBufSize) return 0;
708 
709  if (!b) b = new Bool_t[n];
710 
711  if (sizeof(Bool_t) > 1) {
712  for (int i = 0; i < n; i++)
713  frombuf(fBufCur, &b[i]);
714  } else {
715  Int_t l = sizeof(Bool_t)*n;
716  memcpy(b, fBufCur, l);
717  fBufCur += l;
718  }
719 
720  return n;
721 }
722 
723 ////////////////////////////////////////////////////////////////////////////////
724 /// Read array of characters from the I/O buffer. Returns the number of
725 /// characters read. If argument is a 0 pointer then space will be
726 /// allocated for the array.
727 
729 {
730  R__ASSERT(IsReading());
731 
732  Int_t n;
733  *this >> n;
734  Int_t l = sizeof(Char_t)*n;
735 
736  if (l <= 0 || l > fBufSize) return 0;
737 
738  if (!c) c = new Char_t[n];
739 
740  memcpy(c, fBufCur, l);
741  fBufCur += l;
742 
743  return n;
744 }
745 
746 ////////////////////////////////////////////////////////////////////////////////
747 /// Read array of shorts from the I/O buffer. Returns the number of shorts
748 /// read. If argument is a 0 pointer then space will be allocated for the
749 /// array.
750 
752 {
753  R__ASSERT(IsReading());
754 
755  Int_t n;
756  *this >> n;
757  Int_t l = sizeof(Short_t)*n;
758 
759  if (l <= 0 || l > fBufSize) return 0;
760 
761  if (!h) h = new Short_t[n];
762 
763 #ifdef R__BYTESWAP
764 # ifdef USE_BSWAPCPY
765  bswapcpy16(h, fBufCur, n);
766  fBufCur += l;
767 # else
768  for (int i = 0; i < n; i++)
769  frombuf(fBufCur, &h[i]);
770 # endif
771 #else
772  memcpy(h, fBufCur, l);
773  fBufCur += l;
774 #endif
775 
776  return n;
777 }
778 
779 ////////////////////////////////////////////////////////////////////////////////
780 /// Read array of ints from the I/O buffer. Returns the number of ints
781 /// read. If argument is a 0 pointer then space will be allocated for the
782 /// array.
783 
785 {
786  R__ASSERT(IsReading());
787 
788  Int_t n;
789  *this >> n;
790  Int_t l = sizeof(Int_t)*n;
791 
792  if (l <= 0 || l > fBufSize) return 0;
793 
794  if (!ii) ii = new Int_t[n];
795 
796 #ifdef R__BYTESWAP
797 # ifdef USE_BSWAPCPY
798  bswapcpy32(ii, fBufCur, n);
799  fBufCur += l;
800 # else
801  for (int i = 0; i < n; i++)
802  frombuf(fBufCur, &ii[i]);
803 # endif
804 #else
805  memcpy(ii, fBufCur, l);
806  fBufCur += l;
807 #endif
808 
809  return n;
810 }
811 
812 ////////////////////////////////////////////////////////////////////////////////
813 /// Read array of longs from the I/O buffer. Returns the number of longs
814 /// read. If argument is a 0 pointer then space will be allocated for the
815 /// array.
816 
818 {
819  R__ASSERT(IsReading());
820 
821  Int_t n;
822  *this >> n;
823  Int_t l = sizeof(Long_t)*n;
824 
825  if (l <= 0 || l > fBufSize) return 0;
826 
827  if (!ll) ll = new Long_t[n];
828 
829  TFile *file = (TFile*)fParent;
830  if (file && file->GetVersion() < 30006) {
831  for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
832  } else {
833  for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
834  }
835  return n;
836 }
837 
838 ////////////////////////////////////////////////////////////////////////////////
839 /// Read array of long longs from the I/O buffer. Returns the number of
840 /// long longs read. If argument is a 0 pointer then space will be
841 /// allocated for the array.
842 
844 {
845  R__ASSERT(IsReading());
846 
847  Int_t n;
848  *this >> n;
849  Int_t l = sizeof(Long64_t)*n;
850 
851  if (l <= 0 || l > fBufSize) return 0;
852 
853  if (!ll) ll = new Long64_t[n];
854 
855 #ifdef R__BYTESWAP
856  for (int i = 0; i < n; i++)
857  frombuf(fBufCur, &ll[i]);
858 #else
859  memcpy(ll, fBufCur, l);
860  fBufCur += l;
861 #endif
862 
863  return n;
864 }
865 
866 ////////////////////////////////////////////////////////////////////////////////
867 /// Read array of floats from the I/O buffer. Returns the number of floats
868 /// read. If argument is a 0 pointer then space will be allocated for the
869 /// array.
870 
872 {
873  R__ASSERT(IsReading());
874 
875  Int_t n;
876  *this >> n;
877  Int_t l = sizeof(Float_t)*n;
878 
879  if (l <= 0 || l > fBufSize) return 0;
880 
881  if (!f) f = new Float_t[n];
882 
883 #ifdef R__BYTESWAP
884 # ifdef USE_BSWAPCPY
885  bswapcpy32(f, fBufCur, n);
886  fBufCur += l;
887 # else
888  for (int i = 0; i < n; i++)
889  frombuf(fBufCur, &f[i]);
890 # endif
891 #else
892  memcpy(f, fBufCur, l);
893  fBufCur += l;
894 #endif
895 
896  return n;
897 }
898 
899 ////////////////////////////////////////////////////////////////////////////////
900 /// Read array of doubles from the I/O buffer. Returns the number of doubles
901 /// read. If argument is a 0 pointer then space will be allocated for the
902 /// array.
903 
905 {
906  R__ASSERT(IsReading());
907 
908  Int_t n;
909  *this >> n;
910  Int_t l = sizeof(Double_t)*n;
911 
912  if (l <= 0 || l > fBufSize) return 0;
913 
914  if (!d) d = new Double_t[n];
915 
916 #ifdef R__BYTESWAP
917  for (int i = 0; i < n; i++)
918  frombuf(fBufCur, &d[i]);
919 #else
920  memcpy(d, fBufCur, l);
921  fBufCur += l;
922 #endif
923 
924  return n;
925 }
926 
927 ////////////////////////////////////////////////////////////////////////////////
928 /// Read array of floats (written as truncated float) from the I/O buffer.
929 /// Returns the number of floats read.
930 /// If argument is a 0 pointer then space will be allocated for the array.
931 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16
932 
934 {
935  R__ASSERT(IsReading());
936 
937  Int_t n;
938  *this >> n;
939 
940  if (n <= 0 || 3*n > fBufSize) return 0;
941 
942  if (!f) f = new Float_t[n];
943 
944  ReadFastArrayFloat16(f,n,ele);
945 
946  return n;
947 }
948 
949 ////////////////////////////////////////////////////////////////////////////////
950 /// Read array of doubles (written as float) from the I/O buffer.
951 /// Returns the number of doubles read.
952 /// If argument is a 0 pointer then space will be allocated for the array.
953 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32
954 
956 {
957  R__ASSERT(IsReading());
958 
959  Int_t n;
960  *this >> n;
961 
962  if (n <= 0 || 3*n > fBufSize) return 0;
963 
964  if (!d) d = new Double_t[n];
965 
967 
968  return n;
969 }
970 
971 ////////////////////////////////////////////////////////////////////////////////
972 /// Read array of bools from the I/O buffer. Returns the number of bools
973 /// read.
974 
976 {
977  R__ASSERT(IsReading());
978 
979  Int_t n;
980  *this >> n;
981 
982  if (n <= 0 || n > fBufSize) return 0;
983 
984  if (!b) return 0;
985 
986  if (sizeof(Bool_t) > 1) {
987  for (int i = 0; i < n; i++)
988  frombuf(fBufCur, &b[i]);
989  } else {
990  Int_t l = sizeof(Bool_t)*n;
991  memcpy(b, fBufCur, l);
992  fBufCur += l;
993  }
994 
995  return n;
996 }
997 
998 ////////////////////////////////////////////////////////////////////////////////
999 /// Read array of characters from the I/O buffer. Returns the number of
1000 /// characters read.
1001 
1003 {
1004  R__ASSERT(IsReading());
1005 
1006  Int_t n;
1007  *this >> n;
1008  Int_t l = sizeof(Char_t)*n;
1009 
1010  if (l <= 0 || l > fBufSize) return 0;
1011 
1012  if (!c) return 0;
1013 
1014  memcpy(c, fBufCur, l);
1015  fBufCur += l;
1016 
1017  return n;
1018 }
1019 
1020 ////////////////////////////////////////////////////////////////////////////////
1021 /// Read array of shorts from the I/O buffer. Returns the number of shorts
1022 /// read.
1023 
1025 {
1026  R__ASSERT(IsReading());
1027 
1028  Int_t n;
1029  *this >> n;
1030  Int_t l = sizeof(Short_t)*n;
1031 
1032  if (l <= 0 || l > fBufSize) return 0;
1033 
1034  if (!h) return 0;
1035 
1036 #ifdef R__BYTESWAP
1037 # ifdef USE_BSWAPCPY
1038  bswapcpy16(h, fBufCur, n);
1039  fBufCur += l;
1040 # else
1041  for (int i = 0; i < n; i++)
1042  frombuf(fBufCur, &h[i]);
1043 # endif
1044 #else
1045  memcpy(h, fBufCur, l);
1046  fBufCur += l;
1047 #endif
1048 
1049  return n;
1050 }
1051 
1052 ////////////////////////////////////////////////////////////////////////////////
1053 /// Read array of ints from the I/O buffer. Returns the number of ints
1054 /// read.
1055 
1057 {
1058  R__ASSERT(IsReading());
1059 
1060  Int_t n;
1061  *this >> n;
1062  Int_t l = sizeof(Int_t)*n;
1063 
1064  if (l <= 0 || l > fBufSize) return 0;
1065 
1066  if (!ii) return 0;
1067 
1068 #ifdef R__BYTESWAP
1069 # ifdef USE_BSWAPCPY
1070  bswapcpy32(ii, fBufCur, n);
1071  fBufCur += sizeof(Int_t)*n;
1072 # else
1073  for (int i = 0; i < n; i++)
1074  frombuf(fBufCur, &ii[i]);
1075 # endif
1076 #else
1077  memcpy(ii, fBufCur, l);
1078  fBufCur += l;
1079 #endif
1080 
1081  return n;
1082 }
1083 
1084 ////////////////////////////////////////////////////////////////////////////////
1085 /// Read array of longs from the I/O buffer. Returns the number of longs
1086 /// read.
1087 
1089 {
1090  R__ASSERT(IsReading());
1091 
1092  Int_t n;
1093  *this >> n;
1094  Int_t l = sizeof(Long_t)*n;
1095 
1096  if (l <= 0 || l > fBufSize) return 0;
1097 
1098  if (!ll) return 0;
1099 
1100  TFile *file = (TFile*)fParent;
1101  if (file && file->GetVersion() < 30006) {
1102  for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
1103  } else {
1104  for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
1105  }
1106  return n;
1107 }
1108 
1109 ////////////////////////////////////////////////////////////////////////////////
1110 /// Read array of long longs from the I/O buffer. Returns the number of
1111 /// long longs read.
1112 
1114 {
1115  R__ASSERT(IsReading());
1116 
1117  Int_t n;
1118  *this >> n;
1119  Int_t l = sizeof(Long64_t)*n;
1120 
1121  if (l <= 0 || l > fBufSize) return 0;
1122 
1123  if (!ll) return 0;
1124 
1125 #ifdef R__BYTESWAP
1126  for (int i = 0; i < n; i++)
1127  frombuf(fBufCur, &ll[i]);
1128 #else
1129  memcpy(ll, fBufCur, l);
1130  fBufCur += l;
1131 #endif
1132 
1133  return n;
1134 }
1135 
1136 ////////////////////////////////////////////////////////////////////////////////
1137 /// Read array of floats from the I/O buffer. Returns the number of floats
1138 /// read.
1139 
1141 {
1142  R__ASSERT(IsReading());
1143 
1144  Int_t n;
1145  *this >> n;
1146  Int_t l = sizeof(Float_t)*n;
1147 
1148  if (n <= 0 || l > fBufSize) return 0;
1149 
1150  if (!f) return 0;
1151 
1152 #ifdef R__BYTESWAP
1153 # ifdef USE_BSWAPCPY
1154  bswapcpy32(f, fBufCur, n);
1155  fBufCur += sizeof(Float_t)*n;
1156 # else
1157  for (int i = 0; i < n; i++)
1158  frombuf(fBufCur, &f[i]);
1159 # endif
1160 #else
1161  memcpy(f, fBufCur, l);
1162  fBufCur += l;
1163 #endif
1164 
1165  return n;
1166 }
1167 
1168 ////////////////////////////////////////////////////////////////////////////////
1169 /// Read array of doubles from the I/O buffer. Returns the number of doubles
1170 /// read.
1171 
1173 {
1174  R__ASSERT(IsReading());
1175 
1176  Int_t n;
1177  *this >> n;
1178  Int_t l = sizeof(Double_t)*n;
1179 
1180  if (n <= 0 || l > fBufSize) return 0;
1181 
1182  if (!d) return 0;
1183 
1184 #ifdef R__BYTESWAP
1185  for (int i = 0; i < n; i++)
1186  frombuf(fBufCur, &d[i]);
1187 #else
1188  memcpy(d, fBufCur, l);
1189  fBufCur += l;
1190 #endif
1191 
1192  return n;
1193 }
1194 
1195 ////////////////////////////////////////////////////////////////////////////////
1196 /// Read array of floats (written as truncated float) from the I/O buffer.
1197 /// Returns the number of floats read.
1198 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1199 
1201 {
1202  R__ASSERT(IsReading());
1203 
1204  Int_t n;
1205  *this >> n;
1206 
1207  if (n <= 0 || 3*n > fBufSize) return 0;
1208 
1209  if (!f) return 0;
1210 
1211  ReadFastArrayFloat16(f,n,ele);
1212 
1213  return n;
1214 }
1215 
1216 ////////////////////////////////////////////////////////////////////////////////
1217 /// Read array of doubles (written as float) from the I/O buffer.
1218 /// Returns the number of doubles read.
1219 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1220 
1222 {
1223  R__ASSERT(IsReading());
1224 
1225  Int_t n;
1226  *this >> n;
1227 
1228  if (n <= 0 || 3*n > fBufSize) return 0;
1229 
1230  if (!d) return 0;
1231 
1232  ReadFastArrayDouble32(d,n,ele);
1233 
1234  return n;
1235 }
1236 
1237 ////////////////////////////////////////////////////////////////////////////////
1238 /// Read array of n bools from the I/O buffer.
1239 
1241 {
1242  if (n <= 0 || n > fBufSize) return;
1243 
1244  if (sizeof(Bool_t) > 1) {
1245  for (int i = 0; i < n; i++)
1246  frombuf(fBufCur, &b[i]);
1247  } else {
1248  Int_t l = sizeof(Bool_t)*n;
1249  memcpy(b, fBufCur, l);
1250  fBufCur += l;
1251  }
1252 }
1253 
1254 ////////////////////////////////////////////////////////////////////////////////
1255 /// Read array of n characters from the I/O buffer.
1256 
1258 {
1259  if (n <= 0 || n > fBufSize) return;
1260 
1261  Int_t l = sizeof(Char_t)*n;
1262  memcpy(c, fBufCur, l);
1263  fBufCur += l;
1264 }
1265 
1266 ////////////////////////////////////////////////////////////////////////////////
1267 /// Read array of n characters from the I/O buffer.
1268 
1270 {
1271  Int_t len;
1272  UChar_t lenchar;
1273  *this >> lenchar;
1274  if (lenchar < 255) {
1275  len = lenchar;
1276  } else {
1277  *this >> len;
1278  }
1279  if (len) {
1280  if (len <= 0 || len > fBufSize) return;
1281  Int_t blen = len;
1282  if (len >= n) len = n-1;
1283 
1284  Int_t l = sizeof(Char_t)*len;
1285  memcpy(c, fBufCur, l);
1286  fBufCur += blen;
1287 
1288  c[len] = 0;
1289  } else {
1290  c[0] = 0;
1291  }
1292 }
1293 
1294 ////////////////////////////////////////////////////////////////////////////////
1295 /// Read array of n shorts from the I/O buffer.
1296 
1298 {
1299  Int_t l = sizeof(Short_t)*n;
1300  if (n <= 0 || l > fBufSize) return;
1301 
1302 #ifdef R__BYTESWAP
1303 # ifdef USE_BSWAPCPY
1304  bswapcpy16(h, fBufCur, n);
1305  fBufCur += sizeof(Short_t)*n;
1306 # else
1307  for (int i = 0; i < n; i++)
1308  frombuf(fBufCur, &h[i]);
1309 # endif
1310 #else
1311  memcpy(h, fBufCur, l);
1312  fBufCur += l;
1313 #endif
1314 }
1315 
1316 ////////////////////////////////////////////////////////////////////////////////
1317 /// Read array of n ints from the I/O buffer.
1318 
1320 {
1321  Int_t l = sizeof(Int_t)*n;
1322  if (l <= 0 || l > fBufSize) return;
1323 
1324 #ifdef R__BYTESWAP
1325 # ifdef USE_BSWAPCPY
1326  bswapcpy32(ii, fBufCur, n);
1327  fBufCur += sizeof(Int_t)*n;
1328 # else
1329  for (int i = 0; i < n; i++)
1330  frombuf(fBufCur, &ii[i]);
1331 # endif
1332 #else
1333  memcpy(ii, fBufCur, l);
1334  fBufCur += l;
1335 #endif
1336 }
1337 
1338 ////////////////////////////////////////////////////////////////////////////////
1339 /// Read array of n longs from the I/O buffer.
1340 
1342 {
1343  Int_t l = sizeof(Long_t)*n;
1344  if (l <= 0 || l > fBufSize) return;
1345 
1346  TFile *file = (TFile*)fParent;
1347  if (file && file->GetVersion() < 30006) {
1348  for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
1349  } else {
1350  for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
1351  }
1352 }
1353 
1354 ////////////////////////////////////////////////////////////////////////////////
1355 /// Read array of n long longs from the I/O buffer.
1356 
1358 {
1359  Int_t l = sizeof(Long64_t)*n;
1360  if (l <= 0 || l > fBufSize) return;
1361 
1362 #ifdef R__BYTESWAP
1363  for (int i = 0; i < n; i++)
1364  frombuf(fBufCur, &ll[i]);
1365 #else
1366  memcpy(ll, fBufCur, l);
1367  fBufCur += l;
1368 #endif
1369 }
1370 
1371 ////////////////////////////////////////////////////////////////////////////////
1372 /// Read array of n floats from the I/O buffer.
1373 
1375 {
1376  Int_t l = sizeof(Float_t)*n;
1377  if (l <= 0 || l > fBufSize) return;
1378 
1379 #ifdef R__BYTESWAP
1380 # ifdef USE_BSWAPCPY
1381  bswapcpy32(f, fBufCur, n);
1382  fBufCur += sizeof(Float_t)*n;
1383 # else
1384  for (int i = 0; i < n; i++)
1385  frombuf(fBufCur, &f[i]);
1386 # endif
1387 #else
1388  memcpy(f, fBufCur, l);
1389  fBufCur += l;
1390 #endif
1391 }
1392 
1393 ////////////////////////////////////////////////////////////////////////////////
1394 /// Read array of n doubles from the I/O buffer.
1395 
1397 {
1398  Int_t l = sizeof(Double_t)*n;
1399  if (l <= 0 || l > fBufSize) return;
1400 
1401 #ifdef R__BYTESWAP
1402  for (int i = 0; i < n; i++)
1403  frombuf(fBufCur, &d[i]);
1404 #else
1405  memcpy(d, fBufCur, l);
1406  fBufCur += l;
1407 #endif
1408 }
1409 
1410 ////////////////////////////////////////////////////////////////////////////////
1411 /// Read array of n floats (written as truncated float) from the I/O buffer.
1412 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1413 
1415 {
1416  if (n <= 0 || 3*n > fBufSize) return;
1417 
1418  if (ele && ele->GetFactor() != 0) {
1419  //a range was specified. We read an integer and convert it back to a float
1420  Double_t xmin = ele->GetXmin();
1421  Double_t factor = ele->GetFactor();
1422  for (int j=0;j < n; j++) {
1423  UInt_t aint; *this >> aint; f[j] = (Float_t)(aint/factor + xmin);
1424  }
1425  } else {
1426  Int_t i;
1427  Int_t nbits = 0;
1428  if (ele) nbits = (Int_t)ele->GetXmin();
1429  if (!nbits) nbits = 12;
1430  //we read the exponent and the truncated mantissa of the float
1431  //and rebuild the new float.
1432  union {
1433  Float_t fFloatValue;
1434  Int_t fIntValue;
1435  };
1436  UChar_t theExp;
1437  UShort_t theMan;
1438  for (i = 0; i < n; i++) {
1439  *this >> theExp;
1440  *this >> theMan;
1441  fIntValue = theExp;
1442  fIntValue <<= 23;
1443  fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
1444  if(1<<(nbits+1) & theMan) fFloatValue = -fFloatValue;
1445  f[i] = fFloatValue;
1446  }
1447  }
1448 }
1449 
1450 ////////////////////////////////////////////////////////////////////////////////
1451 /// Read array of n floats (written as truncated float) from the I/O buffer.
1452 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1453 
1455 {
1456  if (n <= 0 || 3*n > fBufSize) return;
1457 
1458  //a range was specified. We read an integer and convert it back to a float
1459  for (int j=0;j < n; j++) {
1460  UInt_t aint; *this >> aint; ptr[j] = (Float_t)(aint/factor + minvalue);
1461  }
1462 }
1463 
1464 ////////////////////////////////////////////////////////////////////////////////
1465 /// Read array of n floats (written as truncated float) from the I/O buffer.
1466 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1467 
1469 {
1470  if (n <= 0 || 3*n > fBufSize) return;
1471 
1472  if (!nbits) nbits = 12;
1473  //we read the exponent and the truncated mantissa of the float
1474  //and rebuild the new float.
1475  union {
1476  Float_t fFloatValue;
1477  Int_t fIntValue;
1478  };
1479  UChar_t theExp;
1480  UShort_t theMan;
1481  for (Int_t i = 0; i < n; i++) {
1482  *this >> theExp;
1483  *this >> theMan;
1484  fIntValue = theExp;
1485  fIntValue <<= 23;
1486  fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
1487  if(1<<(nbits+1) & theMan) fFloatValue = -fFloatValue;
1488  ptr[i] = fFloatValue;
1489  }
1490 }
1491 
1492 ////////////////////////////////////////////////////////////////////////////////
1493 /// Read array of n doubles (written as float) from the I/O buffer.
1494 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1495 
1497 {
1498  if (n <= 0 || 3*n > fBufSize) return;
1499 
1500  if (ele && ele->GetFactor() != 0) {
1501  //a range was specified. We read an integer and convert it back to a double.
1502  Double_t xmin = ele->GetXmin();
1503  Double_t factor = ele->GetFactor();
1504  for (int j=0;j < n; j++) {
1505  UInt_t aint; *this >> aint; d[j] = (Double_t)(aint/factor + xmin);
1506  }
1507  } else {
1508  Int_t i;
1509  Int_t nbits = 0;
1510  if (ele) nbits = (Int_t)ele->GetXmin();
1511  if (!nbits) {
1512  //we read a float and convert it to double
1513  Float_t afloat;
1514  for (i = 0; i < n; i++) {
1515  *this >> afloat;
1516  d[i] = (Double_t)afloat;
1517  }
1518  } else {
1519  //we read the exponent and the truncated mantissa of the float
1520  //and rebuild the double.
1521  union {
1522  Float_t fFloatValue;
1523  Int_t fIntValue;
1524  };
1525  UChar_t theExp;
1526  UShort_t theMan;
1527  for (i = 0; i < n; i++) {
1528  *this >> theExp;
1529  *this >> theMan;
1530  fIntValue = theExp;
1531  fIntValue <<= 23;
1532  fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
1533  if (1<<(nbits+1) & theMan) fFloatValue = -fFloatValue;
1534  d[i] = (Double_t)fFloatValue;
1535  }
1536  }
1537  }
1538 }
1539 
1540 ////////////////////////////////////////////////////////////////////////////////
1541 /// Read array of n doubles (written as float) from the I/O buffer.
1542 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1543 
1545 {
1546  if (n <= 0 || 3*n > fBufSize) return;
1547 
1548  //a range was specified. We read an integer and convert it back to a double.
1549  for (int j=0;j < n; j++) {
1550  UInt_t aint; *this >> aint; d[j] = (Double_t)(aint/factor + minvalue);
1551  }
1552 }
1553 
1554 ////////////////////////////////////////////////////////////////////////////////
1555 /// Read array of n doubles (written as float) from the I/O buffer.
1556 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1557 
1559 {
1560  if (n <= 0 || 3*n > fBufSize) return;
1561 
1562  if (!nbits) {
1563  //we read a float and convert it to double
1564  Float_t afloat;
1565  for (Int_t i = 0; i < n; i++) {
1566  *this >> afloat;
1567  d[i] = (Double_t)afloat;
1568  }
1569  } else {
1570  //we read the exponent and the truncated mantissa of the float
1571  //and rebuild the double.
1572  union {
1573  Float_t fFloatValue;
1574  Int_t fIntValue;
1575  };
1576  UChar_t theExp;
1577  UShort_t theMan;
1578  for (Int_t i = 0; i < n; i++) {
1579  *this >> theExp;
1580  *this >> theMan;
1581  fIntValue = theExp;
1582  fIntValue <<= 23;
1583  fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
1584  if (1<<(nbits+1) & theMan) fFloatValue = -fFloatValue;
1585  d[i] = (Double_t)fFloatValue;
1586  }
1587  }
1588 }
1589 
1590 ////////////////////////////////////////////////////////////////////////////////
1591 /// Read an array of 'n' objects from the I/O buffer.
1592 /// Stores the objects read starting at the address 'start'.
1593 /// The objects in the array are assume to be of class 'cl'.
1594 
1595 void TBufferFile::ReadFastArray(void *start, const TClass *cl, Int_t n,
1596  TMemberStreamer *streamer, const TClass* onFileClass )
1597 {
1598  if (streamer) {
1599  streamer->SetOnFileClass(onFileClass);
1600  (*streamer)(*this,start,0);
1601  return;
1602  }
1603 
1604  int objectSize = cl->Size();
1605  char *obj = (char*)start;
1606  char *end = obj + n*objectSize;
1607 
1608  for(; obj<end; obj+=objectSize) ((TClass*)cl)->Streamer(obj,*this, onFileClass);
1609 }
1610 
1611 ////////////////////////////////////////////////////////////////////////////////
1612 /// Read an array of 'n' objects from the I/O buffer.
1613 ///
1614 /// The objects read are stored starting at the address '*start'
1615 /// The objects in the array are assumed to be of class 'cl' or a derived class.
1616 /// 'mode' indicates whether the data member is marked with '->'
1617 
1618 void TBufferFile::ReadFastArray(void **start, const TClass *cl, Int_t n,
1619  Bool_t isPreAlloc, TMemberStreamer *streamer, const TClass* onFileClass)
1620 {
1621  // if isPreAlloc is true (data member has a ->) we can assume that the pointer (*start)
1622  // is never 0.
1623 
1624  if (streamer) {
1625  if (isPreAlloc) {
1626  for (Int_t j=0;j<n;j++) {
1627  if (!start[j]) start[j] = cl->New();
1628  }
1629  }
1630  streamer->SetOnFileClass(onFileClass);
1631  (*streamer)(*this,(void*)start,0);
1632  return;
1633  }
1634 
1635  if (!isPreAlloc) {
1636 
1637  for (Int_t j=0; j<n; j++){
1638  //delete the object or collection
1639  void *old = start[j];
1640  start[j] = ReadObjectAny(cl);
1641  if (old && old!=start[j] &&
1643  // There are some cases where the user may set up a pointer in the (default)
1644  // constructor but not mark this pointer as transient. Sometime the value
1645  // of this pointer is the address of one of the object with just created
1646  // and the following delete would result in the deletion (possibly of the
1647  // top level object we are goint to return!).
1648  // Eventhough this is a user error, we could prevent the crash by simply
1649  // adding:
1650  // && !CheckObject(start[j],cl)
1651  // However this can increase the read time significantly (10% in the case
1652  // of one TLine pointer in the test/Track and run ./Event 200 0 0 20 30000
1653  //
1654  // If ReadObjectAny returned the same value as we previous had, this means
1655  // that when writing this object (start[j] had already been written and
1656  // is indeed pointing to the same object as the object the user set up
1657  // in the default constructor).
1658  ) {
1659  ((TClass*)cl)->Destructor(old,kFALSE); // call delete and desctructor
1660  }
1661  }
1662 
1663  } else {
1664  //case //-> in comment
1665 
1666  for (Int_t j=0; j<n; j++){
1667  if (!start[j]) start[j] = ((TClass*)cl)->New();
1668  ((TClass*)cl)->Streamer(start[j],*this,onFileClass);
1669  }
1670 
1671  }
1672 }
1673 
1674 ////////////////////////////////////////////////////////////////////////////////
1675 /// Write array of n bools into the I/O buffer.
1676 
1678 {
1679  R__ASSERT(IsWriting());
1680 
1681  *this << n;
1682 
1683  if (n <= 0) return;
1684 
1685  R__ASSERT(b);
1686 
1687  Int_t l = sizeof(UChar_t)*n;
1688  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1689 
1690  if (sizeof(Bool_t) > 1) {
1691  for (int i = 0; i < n; i++)
1692  tobuf(fBufCur, b[i]);
1693  } else {
1694  memcpy(fBufCur, b, l);
1695  fBufCur += l;
1696  }
1697 }
1698 
1699 ////////////////////////////////////////////////////////////////////////////////
1700 /// Write array of n characters into the I/O buffer.
1701 
1703 {
1704  R__ASSERT(IsWriting());
1705 
1706  *this << n;
1707 
1708  if (n <= 0) return;
1709 
1710  R__ASSERT(c);
1711 
1712  Int_t l = sizeof(Char_t)*n;
1713  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1714 
1715  memcpy(fBufCur, c, l);
1716  fBufCur += l;
1717 }
1718 
1719 ////////////////////////////////////////////////////////////////////////////////
1720 /// Write array of n shorts into the I/O buffer.
1721 
1723 {
1724  R__ASSERT(IsWriting());
1725 
1726  *this << n;
1727 
1728  if (n <= 0) return;
1729 
1730  R__ASSERT(h);
1731 
1732  Int_t l = sizeof(Short_t)*n;
1733  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1734 
1735 #ifdef R__BYTESWAP
1736 # ifdef USE_BSWAPCPY
1737  bswapcpy16(fBufCur, h, n);
1738  fBufCur += l;
1739 # else
1740  for (int i = 0; i < n; i++)
1741  tobuf(fBufCur, h[i]);
1742 # endif
1743 #else
1744  memcpy(fBufCur, h, l);
1745  fBufCur += l;
1746 #endif
1747 }
1748 
1749 ////////////////////////////////////////////////////////////////////////////////
1750 /// Write array of n ints into the I/O buffer.
1751 
1753 {
1754  R__ASSERT(IsWriting());
1755 
1756  *this << n;
1757 
1758  if (n <= 0) return;
1759 
1760  R__ASSERT(ii);
1761 
1762  Int_t l = sizeof(Int_t)*n;
1763  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1764 
1765 #ifdef R__BYTESWAP
1766 # ifdef USE_BSWAPCPY
1767  bswapcpy32(fBufCur, ii, n);
1768  fBufCur += l;
1769 # else
1770  for (int i = 0; i < n; i++)
1771  tobuf(fBufCur, ii[i]);
1772 # endif
1773 #else
1774  memcpy(fBufCur, ii, l);
1775  fBufCur += l;
1776 #endif
1777 }
1778 
1779 ////////////////////////////////////////////////////////////////////////////////
1780 /// Write array of n longs into the I/O buffer.
1781 
1783 {
1784  R__ASSERT(IsWriting());
1785 
1786  *this << n;
1787 
1788  if (n <= 0) return;
1789 
1790  R__ASSERT(ll);
1791 
1792  Int_t l = 8*n;
1793  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1794  for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
1795 }
1796 
1797 ////////////////////////////////////////////////////////////////////////////////
1798 /// Write array of n unsigned longs into the I/O buffer.
1799 /// This is an explicit case for unsigned longs since signed longs
1800 /// have a special tobuf().
1801 
1803 {
1804  R__ASSERT(IsWriting());
1805 
1806  *this << n;
1807 
1808  if (n <= 0) return;
1809 
1810  R__ASSERT(ll);
1811 
1812  Int_t l = 8*n;
1813  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1814  for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
1815 }
1816 
1817 ////////////////////////////////////////////////////////////////////////////////
1818 /// Write array of n long longs into the I/O buffer.
1819 
1821 {
1822  R__ASSERT(IsWriting());
1823 
1824  *this << n;
1825 
1826  if (n <= 0) return;
1827 
1828  R__ASSERT(ll);
1829 
1830  Int_t l = sizeof(Long64_t)*n;
1831  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1832 
1833 #ifdef R__BYTESWAP
1834  for (int i = 0; i < n; i++)
1835  tobuf(fBufCur, ll[i]);
1836 #else
1837  memcpy(fBufCur, ll, l);
1838  fBufCur += l;
1839 #endif
1840 }
1841 
1842 ////////////////////////////////////////////////////////////////////////////////
1843 /// Write array of n floats into the I/O buffer.
1844 
1846 {
1847  R__ASSERT(IsWriting());
1848 
1849  *this << n;
1850 
1851  if (n <= 0) return;
1852 
1853  R__ASSERT(f);
1854 
1855  Int_t l = sizeof(Float_t)*n;
1856  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1857 
1858 #ifdef R__BYTESWAP
1859 # ifdef USE_BSWAPCPY
1860  bswapcpy32(fBufCur, f, n);
1861  fBufCur += l;
1862 # else
1863  for (int i = 0; i < n; i++)
1864  tobuf(fBufCur, f[i]);
1865 # endif
1866 #else
1867  memcpy(fBufCur, f, l);
1868  fBufCur += l;
1869 #endif
1870 }
1871 
1872 ////////////////////////////////////////////////////////////////////////////////
1873 /// Write array of n doubles into the I/O buffer.
1874 
1876 {
1877  R__ASSERT(IsWriting());
1878 
1879  *this << n;
1880 
1881  if (n <= 0) return;
1882 
1883  R__ASSERT(d);
1884 
1885  Int_t l = sizeof(Double_t)*n;
1886  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1887 
1888 #ifdef R__BYTESWAP
1889  for (int i = 0; i < n; i++)
1890  tobuf(fBufCur, d[i]);
1891 #else
1892  memcpy(fBufCur, d, l);
1893  fBufCur += l;
1894 #endif
1895 }
1896 
1897 ////////////////////////////////////////////////////////////////////////////////
1898 /// Write array of n floats (as truncated float) into the I/O buffer.
1899 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1900 
1902 {
1903  R__ASSERT(IsWriting());
1904 
1905  *this << n;
1906 
1907  if (n <= 0) return;
1908 
1909  R__ASSERT(f);
1910 
1911  Int_t l = sizeof(Float_t)*n;
1912  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1913 
1914  WriteFastArrayFloat16(f,n,ele);
1915 }
1916 
1917 ////////////////////////////////////////////////////////////////////////////////
1918 /// Write array of n doubles (as float) into the I/O buffer.
1919 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1920 
1922 {
1923  R__ASSERT(IsWriting());
1924 
1925  *this << n;
1926 
1927  if (n <= 0) return;
1928 
1929  R__ASSERT(d);
1930 
1931  Int_t l = sizeof(Float_t)*n;
1932  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1933 
1934  WriteFastArrayDouble32(d,n,ele);
1935 }
1936 
1937 ////////////////////////////////////////////////////////////////////////////////
1938 /// Write array of n bools into the I/O buffer.
1939 
1941 {
1942  if (n <= 0) return;
1943 
1944  Int_t l = sizeof(UChar_t)*n;
1945  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1946 
1947  if (sizeof(Bool_t) > 1) {
1948  for (int i = 0; i < n; i++)
1949  tobuf(fBufCur, b[i]);
1950  } else {
1951  memcpy(fBufCur, b, l);
1952  fBufCur += l;
1953  }
1954 }
1955 
1956 ////////////////////////////////////////////////////////////////////////////////
1957 /// Write array of n characters into the I/O buffer.
1958 
1960 {
1961  if (n <= 0) return;
1962 
1963  Int_t l = sizeof(Char_t)*n;
1964  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1965 
1966  memcpy(fBufCur, c, l);
1967  fBufCur += l;
1968 }
1969 
1970 ////////////////////////////////////////////////////////////////////////////////
1971 /// Write array of n characters into the I/O buffer.
1972 
1974 {
1975  if (n < 255) {
1976  *this << (UChar_t)n;
1977  } else {
1978  *this << (UChar_t)255;
1979  *this << n;
1980  }
1981 
1982  if (n <= 0) return;
1983 
1984  Int_t l = sizeof(Char_t)*n;
1985  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
1986 
1987  memcpy(fBufCur, c, l);
1988  fBufCur += l;
1989 }
1990 
1991 ////////////////////////////////////////////////////////////////////////////////
1992 /// Write array of n shorts into the I/O buffer.
1993 
1995 {
1996  if (n <= 0) return;
1997 
1998  Int_t l = sizeof(Short_t)*n;
1999  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2000 
2001 #ifdef R__BYTESWAP
2002 # ifdef USE_BSWAPCPY
2003  bswapcpy16(fBufCur, h, n);
2004  fBufCur += l;
2005 # else
2006  for (int i = 0; i < n; i++)
2007  tobuf(fBufCur, h[i]);
2008 # endif
2009 #else
2010  memcpy(fBufCur, h, l);
2011  fBufCur += l;
2012 #endif
2013 }
2014 
2015 ////////////////////////////////////////////////////////////////////////////////
2016 /// Write array of n ints into the I/O buffer.
2017 
2019 {
2020  if (n <= 0) return;
2021 
2022  Int_t l = sizeof(Int_t)*n;
2023  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2024 
2025 #ifdef R__BYTESWAP
2026 # ifdef USE_BSWAPCPY
2027  bswapcpy32(fBufCur, ii, n);
2028  fBufCur += l;
2029 # else
2030  for (int i = 0; i < n; i++)
2031  tobuf(fBufCur, ii[i]);
2032 # endif
2033 #else
2034  memcpy(fBufCur, ii, l);
2035  fBufCur += l;
2036 #endif
2037 }
2038 
2039 ////////////////////////////////////////////////////////////////////////////////
2040 /// Write array of n longs into the I/O buffer.
2041 
2043 {
2044  if (n <= 0) return;
2045 
2046  Int_t l = 8*n;
2047  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2048 
2049  for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
2050 }
2051 
2052 ////////////////////////////////////////////////////////////////////////////////
2053 /// Write array of n unsigned longs into the I/O buffer.
2054 /// This is an explicit case for unsigned longs since signed longs
2055 /// have a special tobuf().
2056 
2058 {
2059  if (n <= 0) return;
2060 
2061  Int_t l = 8*n;
2062  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2063 
2064  for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
2065 }
2066 
2067 ////////////////////////////////////////////////////////////////////////////////
2068 /// Write array of n long longs into the I/O buffer.
2069 
2071 {
2072  if (n <= 0) return;
2073 
2074  Int_t l = sizeof(Long64_t)*n;
2075  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2076 
2077 #ifdef R__BYTESWAP
2078  for (int i = 0; i < n; i++)
2079  tobuf(fBufCur, ll[i]);
2080 #else
2081  memcpy(fBufCur, ll, l);
2082  fBufCur += l;
2083 #endif
2084 }
2085 
2086 ////////////////////////////////////////////////////////////////////////////////
2087 /// Write array of n floats into the I/O buffer.
2088 
2090 {
2091  if (n <= 0) return;
2092 
2093  Int_t l = sizeof(Float_t)*n;
2094  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2095 
2096 #ifdef R__BYTESWAP
2097 # ifdef USE_BSWAPCPY
2098  bswapcpy32(fBufCur, f, n);
2099  fBufCur += l;
2100 # else
2101  for (int i = 0; i < n; i++)
2102  tobuf(fBufCur, f[i]);
2103 # endif
2104 #else
2105  memcpy(fBufCur, f, l);
2106  fBufCur += l;
2107 #endif
2108 }
2109 
2110 ////////////////////////////////////////////////////////////////////////////////
2111 /// Write array of n doubles into the I/O buffer.
2112 
2114 {
2115  if (n <= 0) return;
2116 
2117  Int_t l = sizeof(Double_t)*n;
2118  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2119 
2120 #ifdef R__BYTESWAP
2121  for (int i = 0; i < n; i++)
2122  tobuf(fBufCur, d[i]);
2123 #else
2124  memcpy(fBufCur, d, l);
2125  fBufCur += l;
2126 #endif
2127 }
2128 
2129 ////////////////////////////////////////////////////////////////////////////////
2130 /// Write array of n floats (as truncated float) into the I/O buffer.
2131 /// see comments about Float16_t encoding at TBufferFile::WriteFloat16
2132 
2134 {
2135  if (n <= 0) return;
2136 
2137  Int_t l = sizeof(Float_t)*n;
2138  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2139 
2140  if (ele && ele->GetFactor()) {
2141  //A range is specified. We normalize the float to the range and
2142  //convert it to an integer using a scaling factor that is a function of nbits.
2143  //see TStreamerElement::GetRange.
2144  Double_t factor = ele->GetFactor();
2145  Double_t xmin = ele->GetXmin();
2146  Double_t xmax = ele->GetXmax();
2147  for (int j = 0; j < n; j++) {
2148  Float_t x = f[j];
2149  if (x < xmin) x = xmin;
2150  if (x > xmax) x = xmax;
2151  UInt_t aint = UInt_t(0.5+factor*(x-xmin)); *this << aint;
2152  }
2153  } else {
2154  Int_t nbits = 0;
2155  //number of bits stored in fXmin (see TStreamerElement::GetRange)
2156  if (ele) nbits = (Int_t)ele->GetXmin();
2157  if (!nbits) nbits = 12;
2158  Int_t i;
2159  //a range is not specified, but nbits is.
2160  //In this case we truncate the mantissa to nbits and we stream
2161  //the exponent as a UChar_t and the mantissa as a UShort_t.
2162  union {
2163  Float_t fFloatValue;
2164  Int_t fIntValue;
2165  };
2166  for (i = 0; i < n; i++) {
2167  fFloatValue = f[i];
2168  UChar_t theExp = (UChar_t)(0x000000ff & ((fIntValue<<1)>>24));
2169  UShort_t theMan = ((1<<(nbits+1))-1) & (fIntValue>>(23-nbits-1));
2170  theMan++;
2171  theMan = theMan>>1;
2172  if (theMan&1<<nbits) theMan = (1<<nbits) - 1;
2173  if (fFloatValue < 0) theMan |= 1<<(nbits+1);
2174  *this << theExp;
2175  *this << theMan;
2176  }
2177  }
2178 }
2179 
2180 ////////////////////////////////////////////////////////////////////////////////
2181 /// Write array of n doubles (as float) into the I/O buffer.
2182 /// see comments about Double32_t encoding at TBufferFile::WriteDouble32
2183 
2185 {
2186  if (n <= 0) return;
2187 
2188  Int_t l = sizeof(Float_t)*n;
2189  if (fBufCur + l > fBufMax) AutoExpand(fBufSize+l);
2190 
2191  if (ele && ele->GetFactor()) {
2192  //A range is specified. We normalize the double to the range and
2193  //convert it to an integer using a scaling factor that is a function of nbits.
2194  //see TStreamerElement::GetRange.
2195  Double_t factor = ele->GetFactor();
2196  Double_t xmin = ele->GetXmin();
2197  Double_t xmax = ele->GetXmax();
2198  for (int j = 0; j < n; j++) {
2199  Double_t x = d[j];
2200  if (x < xmin) x = xmin;
2201  if (x > xmax) x = xmax;
2202  UInt_t aint = UInt_t(0.5+factor*(x-xmin)); *this << aint;
2203  }
2204  } else {
2205  Int_t nbits = 0;
2206  //number of bits stored in fXmin (see TStreamerElement::GetRange)
2207  if (ele) nbits = (Int_t)ele->GetXmin();
2208  Int_t i;
2209  if (!nbits) {
2210  //if no range and no bits specified, we convert from double to float
2211  for (i = 0; i < n; i++) {
2212  Float_t afloat = (Float_t)d[i];
2213  *this << afloat;
2214  }
2215  } else {
2216  //a range is not specified, but nbits is.
2217  //In this case we truncate the mantissa to nbits and we stream
2218  //the exponent as a UChar_t and the mantissa as a UShort_t.
2219  union {
2220  Float_t fFloatValue;
2221  Int_t fIntValue;
2222  };
2223  for (i = 0; i < n; i++) {
2224  fFloatValue = (Float_t)d[i];
2225  UChar_t theExp = (UChar_t)(0x000000ff & ((fIntValue<<1)>>24));
2226  UShort_t theMan = ((1<<(nbits+1))-1) & (fIntValue>>(23-nbits-1));
2227  theMan++;
2228  theMan = theMan>>1;
2229  if(theMan&1<<nbits) theMan = (1<<nbits) - 1;
2230  if (fFloatValue < 0) theMan |= 1<<(nbits+1);
2231  *this << theExp;
2232  *this << theMan;
2233  }
2234  }
2235  }
2236 }
2237 
2238 ////////////////////////////////////////////////////////////////////////////////
2239 /// Write an array of object starting at the address 'start' and of length 'n'
2240 /// the objects in the array are assumed to be of class 'cl'
2241 
2242 void TBufferFile::WriteFastArray(void *start, const TClass *cl, Int_t n,
2243  TMemberStreamer *streamer)
2244 {
2245  if (streamer) {
2246  (*streamer)(*this, start, 0);
2247  return;
2248  }
2249 
2250  char *obj = (char*)start;
2251  if (!n) n=1;
2252  int size = cl->Size();
2253 
2254  for(Int_t j=0; j<n; j++,obj+=size) {
2255  ((TClass*)cl)->Streamer(obj,*this);
2256  }
2257 }
2258 
2259 ////////////////////////////////////////////////////////////////////////////////
2260 /// Write an array of object starting at the address '*start' and of length 'n'
2261 /// the objects in the array are of class 'cl'
2262 /// 'isPreAlloc' indicates whether the data member is marked with '->'
2263 /// Return:
2264 /// - 0: success
2265 /// - 2: truncated success (i.e actual class is missing. Only ptrClass saved.)
2266 
2268  Bool_t isPreAlloc, TMemberStreamer *streamer)
2269 {
2270  // if isPreAlloc is true (data member has a ->) we can assume that the pointer
2271  // is never 0.
2272 
2273  if (streamer) {
2274  (*streamer)(*this,(void*)start,0);
2275  return 0;
2276  }
2277 
2278  int strInfo = 0;
2279 
2280  Int_t res = 0;
2281 
2282  if (!isPreAlloc) {
2283 
2284  for (Int_t j=0;j<n;j++) {
2285  //must write StreamerInfo if pointer is null
2286  if (!strInfo && !start[j]) {
2287  if (cl->Property() & kIsAbstract) {
2288  // Do not try to generate the StreamerInfo for an abstract class
2289  } else {
2290  TStreamerInfo *info = (TStreamerInfo*)((TClass*)cl)->GetStreamerInfo();
2291  ForceWriteInfo(info,kFALSE);
2292  }
2293  }
2294  strInfo = 2003;
2295  res |= WriteObjectAny(start[j],cl);
2296  }
2297 
2298  } else {
2299  //case //-> in comment
2300 
2301  for (Int_t j=0;j<n;j++) {
2302  if (!start[j]) start[j] = ((TClass*)cl)->New();
2303  ((TClass*)cl)->Streamer(start[j],*this);
2304  }
2305 
2306  }
2307  return res;
2308 }
2309 
2310 ////////////////////////////////////////////////////////////////////////////////
2311 /// Read object from I/O buffer. clReq is NOT used.
2312 ///
2313 /// The value returned is the address of the actual start in memory of
2314 /// the object. Note that if the actual class of the object does not
2315 /// inherit first from TObject, the type of the pointer is NOT 'TObject*'.
2316 /// [More accurately, the class needs to start with the TObject part, for
2317 /// the pointer to be a real TObject*].
2318 /// We recommend using ReadObjectAny instead of ReadObject
2319 
2321 {
2322  return (TObject*) ReadObjectAny(nullptr);
2323 }
2324 
2325 ////////////////////////////////////////////////////////////////////////////////
2326 /// Skip any kind of object from buffer
2327 
2329 {
2330  UInt_t start, count;
2331  ReadVersion(&start, &count);
2332  SetBufferOffset(start+count+sizeof(UInt_t));
2333 }
2334 
2335 ////////////////////////////////////////////////////////////////////////////////
2336 /// Read object from I/O buffer.
2337 ///
2338 /// A typical use for this function is:
2339 ///
2340 /// MyClass *ptr = (MyClass*)b.ReadObjectAny(MyClass::Class());
2341 ///
2342 /// I.e. clCast should point to a TClass object describing the class pointed
2343 /// to by your pointer.
2344 /// In case of multiple inheritance, the return value might not be the
2345 /// real beginning of the object in memory. You will need to use a
2346 /// dynamic_cast later if you need to retrieve it.
2347 
2349 {
2350  R__ASSERT(IsReading());
2351 
2352  // make sure fMap is initialized
2353  InitMap();
2354 
2355  // before reading object save start position
2356  UInt_t startpos = UInt_t(fBufCur-fBuffer);
2357 
2358  // attempt to load next object as TClass clCast
2359  UInt_t tag; // either tag or byte count
2360  TClass *clRef = ReadClass(clCast, &tag);
2361  TClass *clOnfile = nullptr;
2362  Int_t baseOffset = 0;
2363  if (clRef && (clRef!=(TClass*)(-1)) && clCast) {
2364  //baseOffset will be -1 if clRef does not inherit from clCast.
2365  baseOffset = clRef->GetBaseClassOffset(clCast);
2366  if (baseOffset == -1) {
2367  // The 2 classes are unrelated, maybe there is a converter between the 2.
2368 
2369  if (!clCast->GetSchemaRules() ||
2370  !clCast->GetSchemaRules()->HasRuleWithSourceClass(clRef->GetName()))
2371  {
2372  // There is no converter
2373  Error("ReadObject", "got object of wrong class! requested %s but got %s",
2374  clCast->GetName(), clRef->GetName());
2375 
2376  CheckByteCount(startpos, tag, (TClass *)nullptr); // avoid mis-leading byte count error message
2377  return 0; // We better return at this point
2378  }
2379  baseOffset = 0; // For now we do not support requesting from a class that is the base of one of the class for which there is transformation to ....
2380 
2381  Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
2382  clRef = const_cast<TClass*>(clCast);
2383 
2384  }
2385  if (clCast->GetState() > TClass::kEmulated && clRef->GetState() <= TClass::kEmulated) {
2386  //we cannot mix a compiled class with an emulated class in the inheritance
2387  Error("ReadObject", "trying to read an emulated class (%s) to store in a compiled pointer (%s)",
2388  clRef->GetName(),clCast->GetName());
2389  CheckByteCount(startpos, tag, (TClass *)nullptr); // avoid mis-leading byte count error message
2390  return 0;
2391  }
2392  }
2393 
2394  // check if object has not already been read
2395  // (this can only happen when called via CheckObject())
2396  char *obj;
2397  if (fVersion > 0) {
2398  obj = (char *) (Long_t)fMap->GetValue(startpos+kMapOffset);
2399  if (obj == (void*) -1) obj = nullptr;
2400  if (obj) {
2401  CheckByteCount(startpos, tag, (TClass *)nullptr);
2402  return (obj + baseOffset);
2403  }
2404  }
2405 
2406  // unknown class, skip to next object and return 0 obj
2407  if (clRef == (TClass*) -1) {
2408  if (fBufCur >= fBufMax) return 0;
2409  if (fVersion > 0)
2410  MapObject((TObject*) -1, startpos+kMapOffset);
2411  else
2412  MapObject((void*)nullptr, nullptr, fMapCount);
2413  CheckByteCount(startpos, tag, (TClass *)nullptr);
2414  return 0;
2415  }
2416 
2417  if (!clRef) {
2418 
2419  // got a reference to an already read object
2420  if (fVersion > 0) {
2421  tag += fDisplacement;
2422  tag = CheckObject(tag, clCast);
2423  } else {
2424  if (tag > (UInt_t)fMap->GetSize()) {
2425  Error("ReadObject", "object tag too large, I/O buffer corrupted");
2426  return 0;
2427  // exception
2428  }
2429  }
2430  obj = (char *) (Long_t)fMap->GetValue(tag);
2431  clRef = (TClass*) (Long_t)fClassMap->GetValue(tag);
2432 
2433  if (clRef && (clRef!=(TClass*)(-1)) && clCast) {
2434  //baseOffset will be -1 if clRef does not inherit from clCast.
2435  baseOffset = clRef->GetBaseClassOffset(clCast);
2436  if (baseOffset == -1) {
2437  Error("ReadObject", "Got object of wrong class (Got %s while expecting %s)",
2438  clRef->GetName(),clCast->GetName());
2439  // exception
2440  baseOffset = 0;
2441  }
2442  }
2443 
2444  // There used to be a warning printed here when:
2445  // obj && isTObject && !((TObject*)obj)->IsA()->InheritsFrom(clReq)
2446  // however isTObject was based on clReq (now clCast).
2447  // If the test was to fail, then it is as likely that the object is not a TObject
2448  // and then we have a potential core dump.
2449  // At this point (missing clRef), we do NOT have enough information to really
2450  // answer the question: is the object read of the type I requested.
2451 
2452  } else {
2453 
2454  // allocate a new object based on the class found
2455  obj = (char*)clRef->New();
2456  if (!obj) {
2457  Error("ReadObject", "could not create object of class %s",
2458  clRef->GetName());
2459  // exception
2460  return 0;
2461  }
2462 
2463  // add to fMap before reading rest of object
2464  if (fVersion > 0)
2465  MapObject(obj, clRef, startpos+kMapOffset);
2466  else
2467  MapObject(obj, clRef, fMapCount);
2468 
2469  // let the object read itself
2470  clRef->Streamer( obj, *this, clOnfile );
2471 
2472  CheckByteCount(startpos, tag, clRef);
2473  }
2474 
2475  return obj+baseOffset;
2476 }
2477 
2478 ////////////////////////////////////////////////////////////////////////////////
2479 /// Write object to I/O buffer.
2480 /// This function assumes that the value of 'actualObjectStart' is the actual start of
2481 /// the object of class 'actualClass'
2482 /// If 'cacheReuse' is true (default) upon seeing an object address a second time,
2483 /// we record the offset where its was written the first time rather than streaming
2484 /// the object a second time.
2485 /// If 'cacheReuse' is false, we always stream the object. This allows the (re)use
2486 /// of temporary object to store different data in the same buffer.
2487 
2488 void TBufferFile::WriteObjectClass(const void *actualObjectStart, const TClass *actualClass, Bool_t cacheReuse)
2489 {
2490  R__ASSERT(IsWriting());
2491 
2492  if (!actualObjectStart) {
2493 
2494  // save kNullTag to represent NULL pointer
2495  *this << (UInt_t) kNullTag;
2496 
2497  } else {
2498 
2499  // make sure fMap is initialized
2500  InitMap();
2501 
2502  ULong_t idx;
2503  UInt_t slot;
2504  ULong_t hash = Void_Hash(actualObjectStart);
2505 
2506  if ((idx = (ULong_t)fMap->GetValue(hash, (Long_t)actualObjectStart, slot)) != 0) {
2507 
2508  // truncation is OK the value we did put in the map is an 30-bit offset
2509  // and not a pointer
2510  UInt_t objIdx = UInt_t(idx);
2511 
2512  // save index of already stored object
2513  *this << objIdx;
2514 
2515  } else {
2516 
2517  // A warning to let the user know it will need to change the class code
2518  // to be able to read this back.
2519  if (!actualClass->HasDefaultConstructor(kTRUE)) {
2520  Warning("WriteObjectAny", "since %s has no public constructor\n"
2521  "\twhich can be called without argument, objects of this class\n"
2522  "\tcan not be read with the current library. You will need to\n"
2523  "\tadd a default constructor before attempting to read it.",
2524  actualClass->GetName());
2525  }
2526 
2527  // reserve space for leading byte count
2528  UInt_t cntpos = UInt_t(fBufCur-fBuffer);
2529  fBufCur += sizeof(UInt_t);
2530 
2531  // write class of object first
2532  Int_t mapsize = fMap->Capacity(); // The slot depends on the capacity and WriteClass might induce an increase.
2533  WriteClass(actualClass);
2534 
2535  if (cacheReuse) {
2536  // add to map before writing rest of object (to handle self reference)
2537  // (+kMapOffset so it's != kNullTag)
2538  //MapObject(actualObjectStart, actualClass, cntpos+kMapOffset);
2539  UInt_t offset = cntpos+kMapOffset;
2540  if (mapsize == fMap->Capacity()) {
2541  fMap->AddAt(slot, hash, (Long_t)actualObjectStart, offset);
2542  } else {
2543  // The slot depends on the capacity and WriteClass has induced an increase.
2544  fMap->Add(hash, (Long_t)actualObjectStart, offset);
2545  }
2546  // No need to keep track of the class in write mode
2547  // fClassMap->Add(hash, (Long_t)obj, (Long_t)((TObject*)obj)->IsA());
2548  fMapCount++;
2549  }
2550 
2551  ((TClass*)actualClass)->Streamer((void*)actualObjectStart,*this);
2552 
2553  // write byte count
2554  SetByteCount(cntpos);
2555  }
2556  }
2557 }
2558 
2559 ////////////////////////////////////////////////////////////////////////////////
2560 /// Read class definition from I/O buffer.
2561 ///
2562 /// \param[in] clReq Can be used to cross check if the actually read object is of the requested class.
2563 /// \param[in] objTag Set in case the object is a reference to an already read object.
2564 
2566 {
2567  R__ASSERT(IsReading());
2568 
2569  // read byte count and/or tag (older files don't have byte count)
2570  TClass *cl;
2571  if (fBufCur < fBuffer || fBufCur > fBufMax) {
2572  fBufCur = fBufMax;
2573  cl = (TClass*)-1;
2574  return cl;
2575  }
2576  UInt_t bcnt, tag, startpos = 0;
2577  *this >> bcnt;
2578  if (!(bcnt & kByteCountMask) || bcnt == kNewClassTag) {
2579  tag = bcnt;
2580  bcnt = 0;
2581  } else {
2582  fVersion = 1;
2583  startpos = UInt_t(fBufCur-fBuffer);
2584  *this >> tag;
2585  }
2586 
2587  // in case tag is object tag return tag
2588  if (!(tag & kClassMask)) {
2589  if (objTag) *objTag = tag;
2590  return 0;
2591  }
2592 
2593  if (tag == kNewClassTag) {
2594 
2595  // got a new class description followed by a new object
2596  // (class can be 0 if class dictionary is not found, in that
2597  // case object of this class must be skipped)
2598  cl = TClass::Load(*this);
2599 
2600  // add class to fMap for later reference
2601  if (fVersion > 0) {
2602  // check if class was already read
2603  TClass *cl1 = (TClass *)(Long_t)fMap->GetValue(startpos+kMapOffset);
2604  if (cl1 != cl)
2605  MapObject(cl ? cl : (TObject*) -1, startpos+kMapOffset);
2606  } else
2607  MapObject(cl, fMapCount);
2608 
2609  } else {
2610 
2611  // got a tag to an already seen class
2612  UInt_t clTag = (tag & ~kClassMask);
2613 
2614  if (fVersion > 0) {
2615  clTag += fDisplacement;
2616  clTag = CheckObject(clTag, clReq, kTRUE);
2617  } else {
2618  if (clTag == 0 || clTag > (UInt_t)fMap->GetSize()) {
2619  Error("ReadClass", "illegal class tag=%d (0<tag<=%d), I/O buffer corrupted",
2620  clTag, fMap->GetSize());
2621  // exception
2622  }
2623  }
2624 
2625  // class can be 0 if dictionary was not found
2626  cl = (TClass *)(Long_t)fMap->GetValue(clTag);
2627  }
2628 
2629  if (cl && clReq &&
2630  (!cl->InheritsFrom(clReq) &&
2631  !(clReq->GetSchemaRules() &&
2632  clReq->GetSchemaRules()->HasRuleWithSourceClass(cl->GetName()) )
2633  ) ) {
2634  Error("ReadClass", "The on-file class is \"'%s\" which is not compatible with the requested class: \"%s\"",
2635  cl->GetName(), clReq->GetName());
2636  // exception
2637  }
2638 
2639  // return bytecount in objTag
2640  if (objTag) *objTag = (bcnt & ~kByteCountMask);
2641 
2642  // case of unknown class
2643  if (!cl) cl = (TClass*)-1;
2644 
2645  return cl;
2646 }
2647 
2648 ////////////////////////////////////////////////////////////////////////////////
2649 /// Write class description to I/O buffer.
2650 
2652 {
2653  R__ASSERT(IsWriting());
2654 
2655  ULong_t idx;
2656  ULong_t hash = Void_Hash(cl);
2657  UInt_t slot;
2658 
2659  if ((idx = (ULong_t)fMap->GetValue(hash, (Long_t)cl,slot)) != 0) {
2660 
2661  // truncation is OK the value we did put in the map is an 30-bit offset
2662  // and not a pointer
2663  UInt_t clIdx = UInt_t(idx);
2664 
2665  // save index of already stored class
2666  *this << (clIdx | kClassMask);
2667 
2668  } else {
2669 
2670  // offset in buffer where class info is written
2671  UInt_t offset = UInt_t(fBufCur-fBuffer);
2672 
2673  // save new class tag
2674  *this << kNewClassTag;
2675 
2676  // write class name
2677  cl->Store(*this);
2678 
2679  // store new class reference in fMap (+kMapOffset so it's != kNullTag)
2680  CheckCount(offset+kMapOffset);
2681  fMap->AddAt(slot, hash, (Long_t)cl, offset+kMapOffset);
2682  fMapCount++;
2683  }
2684 }
2685 
2686 ////////////////////////////////////////////////////////////////////////////////
2687 /// Skip class version from I/O buffer.
2688 
2690 {
2691  Version_t version;
2692 
2693  // not interested in byte count
2694  frombuf(this->fBufCur,&version);
2695 
2696  // if this is a byte count, then skip next short and read version
2697  if (version & kByteCountVMask) {
2698  frombuf(this->fBufCur,&version);
2699  frombuf(this->fBufCur,&version);
2700  }
2701 
2702  if (cl && cl->GetClassVersion() != 0 && version<=1) {
2703  if (version <= 0) {
2704  UInt_t checksum = 0;
2705  //*this >> checksum;
2706  frombuf(this->fBufCur,&checksum);
2707  TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2708  if (vinfo) {
2709  return;
2710  } else {
2711  // There are some cases (for example when the buffer was stored outside of
2712  // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2713  // the one from the current class, we can still assume that we can read
2714  // the data so let use it.
2715  if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2716  version = cl->GetClassVersion();
2717  } else {
2718  if (fParent) {
2719  Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
2720  checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2721  } else {
2722  Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" (buffer with no parent)",
2723  checksum, cl->GetName());
2724  }
2725  return;
2726  }
2727  }
2728  } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 ) {
2729  // We could have a file created using a Foreign class before
2730  // the introduction of the CheckSum. We need to check
2731  if ((!cl->IsLoaded() || cl->IsForeign()) &&
2732  Class_Has_StreamerInfo(cl) ) {
2733 
2734  const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2735  const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2736  if ( local ) {
2737  UInt_t checksum = local->GetCheckSum();
2738  TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2739  if (vinfo) {
2740  version = vinfo->GetClassVersion();
2741  } else {
2742  Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
2743  checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2744  return;
2745  }
2746  }
2747  else {
2748  Error("SkipVersion", "Class %s not known to file %s.",
2749  cl->GetName(), ((TFile*)fParent)->GetName());
2750  version = 0;
2751  }
2752  }
2753  }
2754  }
2755 }
2756 
2757 ////////////////////////////////////////////////////////////////////////////////
2758 /// Read class version from I/O buffer.
2759 
2761 {
2762  Version_t version;
2763 
2764  if (startpos) {
2765  // before reading object save start position
2766  *startpos = UInt_t(fBufCur-fBuffer);
2767  }
2768 
2769  // read byte count (older files don't have byte count)
2770  // byte count is packed in two individual shorts, this to be
2771  // backward compatible with old files that have at this location
2772  // only a single short (i.e. the version)
2773  union {
2774  UInt_t cnt;
2775  Version_t vers[2];
2776  } v;
2777 #ifdef R__BYTESWAP
2778  frombuf(this->fBufCur,&v.vers[1]);
2779  frombuf(this->fBufCur,&v.vers[0]);
2780 #else
2781  frombuf(this->fBufCur,&v.vers[0]);
2782  frombuf(this->fBufCur,&v.vers[1]);
2783 #endif
2784 
2785  // no bytecount, backup and read version
2786  if (!(v.cnt & kByteCountMask)) {
2787  fBufCur -= sizeof(UInt_t);
2788  v.cnt = 0;
2789  }
2790  if (bcnt) *bcnt = (v.cnt & ~kByteCountMask);
2791  frombuf(this->fBufCur,&version);
2792 
2793  if (version<=1) {
2794  if (version <= 0) {
2795  if (cl) {
2796  if (cl->GetClassVersion() != 0
2797  // If v.cnt < 6 then we have a class with a version that used to be zero and so there is no checksum.
2798  && (v.cnt && v.cnt >= 6)
2799  ) {
2800  UInt_t checksum = 0;
2801  //*this >> checksum;
2802  frombuf(this->fBufCur,&checksum);
2803  TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2804  if (vinfo) {
2805  return vinfo->TStreamerInfo::GetClassVersion(); // Try to get inlining.
2806  } else {
2807  // There are some cases (for example when the buffer was stored outside of
2808  // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2809  // the one from the current class, we can still assume that we can read
2810  // the data so let use it.
2811  if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2812  version = cl->GetClassVersion();
2813  } else {
2814  if (fParent) {
2815  Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" in %s.",
2816  checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2817  } else {
2818  Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" (buffer with no parent)",
2819  checksum, cl->GetName());
2820  }
2821  return 0;
2822  }
2823  }
2824  }
2825  } else { // of if (cl) {
2826  UInt_t checksum = 0;
2827  //*this >> checksum;
2828  // If *bcnt < 6 then we have a class with 'just' version zero and no checksum
2829  if (v.cnt && v.cnt >= 6)
2830  frombuf(this->fBufCur,&checksum);
2831  }
2832  } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 && cl && cl->GetClassVersion() != 0) {
2833  // We could have a file created using a Foreign class before
2834  // the introduction of the CheckSum. We need to check
2835  if ((!cl->IsLoaded() || cl->IsForeign()) &&
2836  Class_Has_StreamerInfo(cl) ) {
2837 
2838  const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2839  const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2840  if ( local ) {
2841  UInt_t checksum = local->GetCheckSum();
2842  TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2843  if (vinfo) {
2844  version = vinfo->GetClassVersion();
2845  } else {
2846  Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" in %s.",
2847  checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2848  return 0;
2849  }
2850  }
2851  else {
2852  Error("ReadVersion", "Class %s not known to file %s.",
2853  cl->GetName(), ((TFile*)fParent)->GetName());
2854  version = 0;
2855  }
2856  }
2857  }
2858  }
2859  return version;
2860 }
2861 
2862 ////////////////////////////////////////////////////////////////////////////////
2863 /// Read class version from I/O buffer, when the caller knows for sure that
2864 /// there is no checksum written/involved.
2865 
2867 {
2868  Version_t version;
2869 
2870  if (startpos) {
2871  // before reading object save start position
2872  *startpos = UInt_t(fBufCur-fBuffer);
2873  }
2874 
2875  // read byte count (older files don't have byte count)
2876  // byte count is packed in two individual shorts, this to be
2877  // backward compatible with old files that have at this location
2878  // only a single short (i.e. the version)
2879  union {
2880  UInt_t cnt;
2881  Version_t vers[2];
2882  } v;
2883 #ifdef R__BYTESWAP
2884  frombuf(this->fBufCur,&v.vers[1]);
2885  frombuf(this->fBufCur,&v.vers[0]);
2886 #else
2887  frombuf(this->fBufCur,&v.vers[0]);
2888  frombuf(this->fBufCur,&v.vers[1]);
2889 #endif
2890 
2891  // no bytecount, backup and read version
2892  if (!(v.cnt & kByteCountMask)) {
2893  fBufCur -= sizeof(UInt_t);
2894  v.cnt = 0;
2895  }
2896  if (bcnt) *bcnt = (v.cnt & ~kByteCountMask);
2897  frombuf(this->fBufCur,&version);
2898 
2899  return version;
2900 }
2901 
2902 ////////////////////////////////////////////////////////////////////////////////
2903 /// Read class version from I/O buffer
2904 ///
2905 /// To be used when streaming out member-wise streamed collection where we do not
2906 /// care (not save) about the byte count and can safely ignore missing streamerInfo
2907 /// (since they usually indicate empty collections).
2908 
2910 {
2911  Version_t version;
2912 
2913  // not interested in byte count
2914  frombuf(this->fBufCur,&version);
2915 
2916  if (version<=1) {
2917  if (version <= 0) {
2918  if (cl) {
2919  if (cl->GetClassVersion() != 0) {
2920  UInt_t checksum = 0;
2921  frombuf(this->fBufCur,&checksum);
2922  TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2923  if (vinfo) {
2924  return vinfo->TStreamerInfo::GetClassVersion(); // Try to get inlining.
2925  } else {
2926  // There are some cases (for example when the buffer was stored outside of
2927  // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2928  // the one from the current class, we can still assume that we can read
2929  // the data so let use it.
2930  if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2931  version = cl->GetClassVersion();
2932  } else {
2933  // If we can not find the streamerInfo this means that
2934  // we do not actually need it (the collection is always empty
2935  // in this file), so no need to issue a warning.
2936  return 0;
2937  }
2938  }
2939  }
2940  } else { // of if (cl) {
2941  UInt_t checksum = 0;
2942  frombuf(this->fBufCur,&checksum);
2943  }
2944  } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 && cl && cl->GetClassVersion() != 0) {
2945  // We could have a file created using a Foreign class before
2946  // the introduction of the CheckSum. We need to check
2947  if ((!cl->IsLoaded() || cl->IsForeign()) && Class_Has_StreamerInfo(cl) ) {
2948 
2949  const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2950  const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2951  if ( local ) {
2952  UInt_t checksum = local->GetCheckSum();
2953  TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2954  if (vinfo) {
2955  version = vinfo->GetClassVersion();
2956  } else {
2957  // If we can not find the streamerInfo this means that
2958  // we do not actually need it (the collection is always empty
2959  // in this file), so no need to issue a warning.
2960  return 0;
2961  }
2962  }
2963  else {
2964  Error("ReadVersion", "Class %s not known to file %s.",
2965  cl->GetName(), ((TFile*)fParent)->GetName());
2966  version = 0;
2967  }
2968  }
2969  }
2970  }
2971  return version;
2972 }
2973 
2974 ////////////////////////////////////////////////////////////////////////////////
2975 /// Write class version to I/O buffer.
2976 
2978 {
2979  UInt_t cntpos = 0;
2980  if (useBcnt) {
2981  // reserve space for leading byte count
2982  cntpos = UInt_t(fBufCur-fBuffer);
2983  fBufCur += sizeof(UInt_t);
2984  }
2985 
2986  Version_t version = cl->GetClassVersion();
2987  if (version<=1 && cl->IsForeign()) {
2988  *this << Version_t(0);
2989  *this << cl->GetCheckSum();
2990  } else {
2991  if (version > kMaxVersion) {
2992  Error("WriteVersion", "version number cannot be larger than %hd)",
2993  kMaxVersion);
2994  version = kMaxVersion;
2995  }
2996  *this <<version;
2997  }
2998 
2999  // return position where to store possible byte count
3000  return cntpos;
3001 }
3002 
3003 ////////////////////////////////////////////////////////////////////////////////
3004 /// Write class version to I/O buffer after setting the kStreamedMemberWise
3005 /// bit in the version number.
3006 
3008 {
3009  UInt_t cntpos = 0;
3010  if (useBcnt) {
3011  // reserve space for leading byte count
3012  cntpos = UInt_t(fBufCur-fBuffer);
3013  fBufCur += sizeof(UInt_t);
3014  }
3015 
3016  Version_t version = cl->GetClassVersion();
3017  if (version<=1 && cl->IsForeign()) {
3018  Error("WriteVersionMemberWise", "Member-wise streaming of foreign collection not yet implemented!");
3019  *this << Version_t(0);
3020  *this << cl->GetCheckSum();
3021  } else {
3022  if (version > kMaxVersion) {
3023  Error("WriteVersionMemberWise", "version number cannot be larger than %hd)",
3024  kMaxVersion);
3025  version = kMaxVersion;
3026  }
3027  version |= kStreamedMemberWise;
3028  *this <<version;
3029  }
3030 
3031  // return position where to store possible byte count
3032  return cntpos;
3033 }
3034 
3035 ////////////////////////////////////////////////////////////////////////////////
3036 /// Stream an object given its C++ typeinfo information.
3037 
3038 void TBufferFile::StreamObject(void *obj, const std::type_info &typeinfo, const TClass* onFileClass )
3039 {
3040  TClass *cl = TClass::GetClass(typeinfo);
3041  if (cl) cl->Streamer(obj, *this, (TClass*)onFileClass );
3042  else Warning("StreamObject","No TClass for the type %s is available, the object was not read.", typeinfo.name());
3043 }
3044 
3045 ////////////////////////////////////////////////////////////////////////////////
3046 /// Stream an object given the name of its actual class.
3047 
3048 void TBufferFile::StreamObject(void *obj, const char *className, const TClass* onFileClass)
3049 {
3050  TClass *cl = TClass::GetClass(className);
3051  if (cl) cl->Streamer(obj, *this, (TClass*)onFileClass );
3052  else Warning("StreamObject","No TClass for the type %s is available, the object was not read.", className);
3053 }
3054 
3055 ////////////////////////////////////////////////////////////////////////////////
3056 /// Stream an object given a pointer to its actual class.
3057 
3058 void TBufferFile::StreamObject(void *obj, const TClass *cl, const TClass* onFileClass )
3059 {
3060  ((TClass*)cl)->Streamer(obj, *this, (TClass*)onFileClass );
3061 }
3062 
3063 ////////////////////////////////////////////////////////////////////////////////
3064 /// Stream an object inheriting from TObject using its streamer.
3065 
3067 {
3068  obj->Streamer(*this);
3069 }
3070 
3071 ////////////////////////////////////////////////////////////////////////////////
3072 /// Check if offset is not too large (< kMaxMapCount) when writing.
3073 
3075 {
3076  if (IsWriting()) {
3077  if (offset >= kMaxMapCount) {
3078  Error("CheckCount", "buffer offset too large (larger than %d)", kMaxMapCount);
3079  // exception
3080  }
3081  }
3082 }
3083 
3084 ////////////////////////////////////////////////////////////////////////////////
3085 /// Check for object in the read map. If the object is 0 it still has to be
3086 /// read. Try to read it from the buffer starting at location offset. If the
3087 /// object is -1 then it really does not exist and we return 0. If the object
3088 /// exists just return the offset.
3089 
3090 UInt_t TBufferFile::CheckObject(UInt_t offset, const TClass *cl, Bool_t readClass)
3091 {
3092  // in position 0 we always have the reference to the null object
3093  if (!offset) return offset;
3094 
3095  Long_t cli;
3096 
3097  if (readClass) {
3098  if ((cli = fMap->GetValue(offset)) == 0) {
3099  // No class found at this location in map. It might have been skipped
3100  // as part of a skipped object. Try to explicitly read the class.
3101 
3102  // save fBufCur and set to place specified by offset (-kMapOffset-sizeof(bytecount))
3103  char *bufsav = fBufCur;
3104  fBufCur = (char *)(fBuffer + offset-kMapOffset-sizeof(UInt_t));
3105 
3106  TClass *c = ReadClass(cl);
3107  if (c == (TClass*) -1) {
3108  // mark class as really not available
3109  fMap->Remove(offset);
3110  fMap->Add(offset, -1);
3111  offset = 0;
3112  if (cl)
3113  Warning("CheckObject", "reference to unavailable class %s,"
3114  " pointers of this type will be 0", cl->GetName());
3115  else
3116  Warning("CheckObject", "reference to an unavailable class,"
3117  " pointers of that type will be 0");
3118  }
3119 
3120  fBufCur = bufsav;
3121 
3122  } else if (cli == -1) {
3123 
3124  // class really does not exist
3125  return 0;
3126  }
3127 
3128  } else {
3129 
3130  if ((cli = fMap->GetValue(offset)) == 0) {
3131  // No object found at this location in map. It might have been skipped
3132  // as part of a skipped object. Try to explicitly read the object.
3133 
3134  // save fBufCur and set to place specified by offset (-kMapOffset)
3135  char *bufsav = fBufCur;
3136  fBufCur = (char *)(fBuffer + offset-kMapOffset);
3137 
3138  TObject *obj = ReadObject(cl);
3139  if (!obj) {
3140  // mark object as really not available
3141  fMap->Remove(offset);
3142  fMap->Add(offset, -1);
3143  Warning("CheckObject", "reference to object of unavailable class %s, offset=%d"
3144  " pointer will be 0", cl ? cl->GetName() : "TObject",offset);
3145  offset = 0;
3146  }
3147 
3148  fBufCur = bufsav;
3149 
3150  } else if (cli == -1) {
3151 
3152  // object really does not exist
3153  return 0;
3154  }
3155 
3156  }
3157 
3158  return offset;
3159 }
3160 
3161 
3162 ////////////////////////////////////////////////////////////////////////////////
3163 /// Read max bytes from the I/O buffer into buf. The function returns
3164 /// the actual number of bytes read.
3165 
3167 {
3168  R__ASSERT(IsReading());
3169 
3170  if (max == 0) return 0;
3171 
3172  Int_t n = TMath::Min(max, (Int_t)(fBufMax - fBufCur));
3173 
3174  memcpy(buf, fBufCur, n);
3175  fBufCur += n;
3176 
3177  return n;
3178 }
3179 
3180 ////////////////////////////////////////////////////////////////////////////////
3181 /// Write max bytes from buf into the I/O buffer.
3182 
3183 void TBufferFile::WriteBuf(const void *buf, Int_t max)
3184 {
3185  R__ASSERT(IsWriting());
3186 
3187  if (max == 0) return;
3188 
3189  if (fBufCur + max > fBufMax) AutoExpand(fBufSize+max); // a more precise request would be: fBufSize + max - (fBufMax - fBufCur)
3190 
3191  memcpy(fBufCur, buf, max);
3192  fBufCur += max;
3193 }
3194 
3195 ////////////////////////////////////////////////////////////////////////////////
3196 /// Read string from I/O buffer. String is read till 0 character is
3197 /// found or till max-1 characters are read (i.e. string s has max
3198 /// bytes allocated). If max = -1 no check on number of character is
3199 /// made, reading continues till 0 character is found.
3200 
3202 {
3203  R__ASSERT(IsReading());
3204 
3205  char ch;
3206  Int_t nr = 0;
3207 
3208  if (max == -1) max = kMaxInt;
3209 
3210  while (nr < max-1) {
3211 
3212  *this >> ch;
3213 
3214  // stop when 0 read
3215  if (ch == 0) break;
3216 
3217  s[nr++] = ch;
3218  }
3219 
3220  s[nr] = 0;
3221  return s;
3222 }
3223 
3224 ////////////////////////////////////////////////////////////////////////////////
3225 /// Write string to I/O buffer. Writes string upto and including the
3226 /// terminating 0.
3227 
3228 void TBufferFile::WriteString(const char *s)
3229 {
3230  WriteBuf(s, (strlen(s)+1)*sizeof(char));
3231 }
3232 
3233 ////////////////////////////////////////////////////////////////////////////////
3234 /// Read emulated class.
3235 
3236 Int_t TBufferFile::ReadClassEmulated(const TClass *cl, void *object, const TClass *onFileClass)
3237 {
3238  UInt_t start,count;
3239  //We assume that the class was written with a standard streamer
3240  //We attempt to recover if a version count was not written
3241  Version_t v = ReadVersion(&start,&count);
3242 
3243  if (count) {
3244  TStreamerInfo *sinfo = nullptr;
3245  if( onFileClass ) {
3246  sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, v );
3247  if( !sinfo )
3248  return 0;
3249  }
3250 
3251  sinfo = (TStreamerInfo*)cl->GetStreamerInfo(v);
3252  ApplySequence(*(sinfo->GetReadObjectWiseActions()), object);
3253  if (sinfo->IsRecovered()) count=0;
3254  CheckByteCount(start,count,cl);
3255  } else {
3256  SetBufferOffset(start);
3257  TStreamerInfo *sinfo = ((TStreamerInfo*)cl->GetStreamerInfo());
3258  ApplySequence(*(sinfo->GetReadObjectWiseActions()), object);
3259  }
3260  return 0;
3261 }
3262 
3263 ////////////////////////////////////////////////////////////////////////////////
3264 /// Deserialize information from a buffer into an object.
3265 ///
3266 /// Note: This function is called by the xxx::Streamer() functions in
3267 /// rootcint-generated dictionaries.
3268 /// This function assumes that the class version and the byte count
3269 /// information have been read.
3270 ///
3271 /// \param[in] version The version number of the class
3272 /// \param[in] start The starting position in the buffer b
3273 /// \param[in] count The number of bytes for this object in the buffer
3274 ///
3275 
3276 Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, Int_t version, UInt_t start, UInt_t count, const TClass *onFileClass)
3277 {
3278 
3279  //---------------------------------------------------------------------------
3280  // The ondisk class has been specified so get foreign streamer info
3281  /////////////////////////////////////////////////////////////////////////////
3282 
3283  TStreamerInfo *sinfo = nullptr;
3284  if( onFileClass ) {
3285  sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, version );
3286  if( !sinfo ) {
3287  Error("ReadClassBuffer",
3288  "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
3289  onFileClass->GetName(), version, cl->GetName(), Length() );
3290  CheckByteCount(start, count, onFileClass);
3291  return 0;
3292  }
3293  }
3294  //---------------------------------------------------------------------------
3295  // Get local streamer info
3296  /////////////////////////////////////////////////////////////////////////////
3297  /// The StreamerInfo should exist at this point.
3298 
3299  else {
3301  auto infos = cl->GetStreamerInfos();
3302  auto ninfos = infos->GetSize();
3303  if (version < -1 || version >= ninfos) {
3304  Error("ReadClassBuffer", "class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
3305  cl->GetName(), version, Length() );
3306  CheckByteCount(start, count, cl);
3307  return 0;
3308  }
3309  sinfo = (TStreamerInfo*)infos->At(version);
3310  if (sinfo == nullptr) {
3311  // Unless the data is coming via a socket connection from with schema evolution
3312  // (tracking) was not enabled. So let's create the StreamerInfo if it is the
3313  // one for the current version, otherwise let's complain ...
3314  // We could also get here if there old class version was '1' and the new class version is higher than 1
3315  // AND the checksum is the same.
3316  if ( version == cl->GetClassVersion() || version == 1 ) {
3317  const_cast<TClass*>(cl)->BuildRealData(pointer);
3318  // This creation is alright since we just checked within the
3319  // current 'locked' section.
3320  sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
3321  const_cast<TClass*>(cl)->RegisterStreamerInfo(sinfo);
3322  if (gDebug > 0) Info("ReadClassBuffer", "Creating StreamerInfo for class: %s, version: %d", cl->GetName(), version);
3323  sinfo->Build();
3324  } else if (version==0) {
3325  // When the object was written the class was version zero, so
3326  // there is no StreamerInfo to be found.
3327  // Check that the buffer position corresponds to the byte count.
3328  CheckByteCount(start, count, cl);
3329  return 0;
3330  } else {
3331  Error("ReadClassBuffer", "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
3332  version, cl->GetName(), Length() );
3333  CheckByteCount(start, count, cl);
3334  return 0;
3335  }
3336  } else if (!sinfo->IsCompiled()) { // Note this read is protected by the above lock.
3337  // Streamer info has not been compiled, but exists.
3338  // Therefore it was read in from a file and we have to do schema evolution.
3339  const_cast<TClass*>(cl)->BuildRealData(pointer);
3340  sinfo->BuildOld();
3341  }
3342  }
3343 
3344  // Deserialize the object.
3345  ApplySequence(*(sinfo->GetReadObjectWiseActions()), (char*)pointer);
3346  if (sinfo->IsRecovered()) count=0;
3347 
3348  // Check that the buffer position corresponds to the byte count.
3349  CheckByteCount(start, count, cl);
3350  return 0;
3351 }
3352 
3353 ////////////////////////////////////////////////////////////////////////////////
3354 /// Deserialize information from a buffer into an object.
3355 ///
3356 /// Note: This function is called by the xxx::Streamer()
3357 /// functions in rootcint-generated dictionaries.
3358 ///
3359 
3360 Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onFileClass)
3361 {
3362  // Read the class version from the buffer.
3363  UInt_t R__s = 0; // Start of object.
3364  UInt_t R__c = 0; // Count of bytes.
3365  Version_t version;
3366 
3367  if( onFileClass )
3368  version = ReadVersion(&R__s, &R__c, onFileClass);
3369  else
3370  version = ReadVersion(&R__s, &R__c, cl);
3371 
3372  Bool_t v2file = kFALSE;
3373  TFile *file = (TFile*)GetParent();
3374  if (file && file->GetVersion() < 30000) {
3375  version = -1; //This is old file
3376  v2file = kTRUE;
3377  }
3378 
3379  //---------------------------------------------------------------------------
3380  // The ondisk class has been specified so get foreign streamer info
3381  /////////////////////////////////////////////////////////////////////////////
3382 
3383  TStreamerInfo *sinfo = nullptr;
3384  if( onFileClass ) {
3385  sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, version );
3386  if( !sinfo ) {
3387  Error("ReadClassBuffer",
3388  "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
3389  onFileClass->GetName(), version, cl->GetName(), Length() );
3390  CheckByteCount(R__s, R__c, onFileClass);
3391  return 0;
3392  }
3393  }
3394  //---------------------------------------------------------------------------
3395  // Get local streamer info
3396  /////////////////////////////////////////////////////////////////////////////
3397  /// The StreamerInfo should exist at this point.
3398 
3399  else {
3400  TStreamerInfo *guess = (TStreamerInfo*)cl->GetLastReadInfo();
3401  if (guess && guess->GetClassVersion() == version) {
3402  sinfo = guess;
3403  } else {
3404  // The last one is not the one we are looking for.
3405  {
3407 
3408  const TObjArray *infos = cl->GetStreamerInfos();
3409  Int_t infocapacity = infos->Capacity();
3410  if (infocapacity) {
3411  if (version < -1 || version >= infocapacity) {
3412  Error("ReadClassBuffer","class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
3413  cl->GetName(), version, Length());
3414  CheckByteCount(R__s, R__c, cl);
3415  return 0;
3416  }
3417  sinfo = (TStreamerInfo*) infos->UncheckedAt(version);
3418  if (sinfo) {
3419  if (!sinfo->IsCompiled())
3420  {
3421  // Streamer info has not been compiled, but exists.
3422  // Therefore it was read in from a file and we have to do schema evolution?
3424  const_cast<TClass*>(cl)->BuildRealData(pointer);
3425  sinfo->BuildOld();
3426  }
3427  // If the compilation succeeded, remember this StreamerInfo.
3428  // const_cast okay because of the lock on gInterpreterMutex.
3429  if (sinfo->IsCompiled()) const_cast<TClass*>(cl)->SetLastReadInfo(sinfo);
3430  }
3431  }
3432  }
3433 
3434  if (sinfo == nullptr) {
3435  // Unless the data is coming via a socket connection from with schema evolution
3436  // (tracking) was not enabled. So let's create the StreamerInfo if it is the
3437  // one for the current version, otherwise let's complain ...
3438  // We could also get here when reading a file prior to the introduction of StreamerInfo.
3439  // We could also get here if there old class version was '1' and the new class version is higher than 1
3440  // AND the checksum is the same.
3441  if (v2file || version == cl->GetClassVersion() || version == 1 ) {
3443 
3444  // We need to check if another thread did not get here first
3445  // and did the StreamerInfo creation already.
3446  auto infos = cl->GetStreamerInfos();
3447  auto ninfos = infos->GetSize();
3448  if (!(version < -1 || version >= ninfos)) {
3449  sinfo = (TStreamerInfo *) infos->At(version);
3450  }
3451  if (!sinfo) {
3452  const_cast<TClass *>(cl)->BuildRealData(pointer);
3453  sinfo = new TStreamerInfo(const_cast<TClass *>(cl));
3454  sinfo->SetClassVersion(version);
3455  const_cast<TClass *>(cl)->RegisterStreamerInfo(sinfo);
3456  if (gDebug > 0)
3457  Info("ReadClassBuffer", "Creating StreamerInfo for class: %s, version: %d",
3458  cl->GetName(), version);
3459  if (v2file) {
3460  sinfo->Build(); // Get the elements.
3461  sinfo->Clear("build"); // Undo compilation.
3462  sinfo->BuildEmulated(file); // Fix the types and redo compilation.
3463  } else {
3464  sinfo->Build();
3465  }
3466  }
3467  } else if (version==0) {
3468  // When the object was written the class was version zero, so
3469  // there is no StreamerInfo to be found.
3470  // Check that the buffer position corresponds to the byte count.
3471  CheckByteCount(R__s, R__c, cl);
3472  return 0;
3473  } else {
3474  Error( "ReadClassBuffer", "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
3475  version, cl->GetName(), Length() );
3476  CheckByteCount(R__s, R__c, cl);
3477  return 0;
3478  }
3479  }
3480  }
3481  }
3482 
3483  //deserialize the object
3484  ApplySequence(*(sinfo->GetReadObjectWiseActions()), (char*)pointer );
3485  if (sinfo->TStreamerInfo::IsRecovered()) R__c=0; // 'TStreamerInfo::' avoids going via a virtual function.
3486 
3487  // Check that the buffer position corresponds to the byte count.
3488  CheckByteCount(R__s, R__c, cl);
3489 
3490  if (gDebug > 2) Info("ReadClassBuffer", "For class: %s has read %d bytes", cl->GetName(), R__c);
3491 
3492  return 0;
3493 }
3494 
3495 ////////////////////////////////////////////////////////////////////////////////
3496 /// Function called by the Streamer functions to serialize object at p
3497 /// to buffer b. The optional argument info may be specified to give an
3498 /// alternative StreamerInfo instead of using the default StreamerInfo
3499 /// automatically built from the class definition.
3500 /// For more information, see class TStreamerInfo.
3501 
3502 Int_t TBufferFile::WriteClassBuffer(const TClass *cl, void *pointer)
3503 {
3504  //build the StreamerInfo if first time for the class
3505  TStreamerInfo *sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetCurrentStreamerInfo();
3506  if (sinfo == nullptr) {
3507  //Have to be sure between the check and the taking of the lock if the current streamer has changed
3509  sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetCurrentStreamerInfo();
3510  if (sinfo == nullptr) {
3511  const_cast<TClass*>(cl)->BuildRealData(pointer);
3512  sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
3513  const_cast<TClass*>(cl)->SetCurrentStreamerInfo(sinfo);
3514  const_cast<TClass*>(cl)->RegisterStreamerInfo(sinfo);
3515  if (gDebug > 0) Info("WritedClassBuffer", "Creating StreamerInfo for class: %s, version: %d",cl->GetName(),cl->GetClassVersion());
3516  sinfo->Build();
3517  }
3518  } else if (!sinfo->IsCompiled()) {
3520  // Redo the test in case we have been victim of a data race on fIsCompiled.
3521  if (!sinfo->IsCompiled()) {
3522  const_cast<TClass*>(cl)->BuildRealData(pointer);
3523  sinfo->BuildOld();
3524  }
3525  }
3526 
3527  //write the class version number and reserve space for the byte count
3528  UInt_t R__c = WriteVersion(cl, kTRUE);
3529 
3530  //NOTE: In the future Philippe wants this to happen via a custom action
3531  TagStreamerInfo(sinfo);
3532  ApplySequence(*(sinfo->GetWriteObjectWiseActions()), (char*)pointer);
3533 
3534  //write the byte count at the start of the buffer
3535  SetByteCount(R__c, kTRUE);
3536 
3537  if (gDebug > 2) Info("WritedClassBuffer", "For class: %s version %d has written %d bytes",cl->GetName(),cl->GetClassVersion(),UInt_t(fBufCur - fBuffer) - R__c - (UInt_t)sizeof(UInt_t));
3538  return 0;
3539 }
3540 
3541 ////////////////////////////////////////////////////////////////////////////////
3542 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3543 /// The collection needs to be a split TClonesArray or a split vector of pointers.
3544 
3546 {
3547  if (gDebug) {
3548  //loop on all active members
3549  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3550  for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3551  iter != end;
3552  ++iter) {
3553  (*iter).PrintDebug(*this,obj);
3554  (*iter)(*this,obj);
3555  }
3556 
3557  } else {
3558  //loop on all active members
3559  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3560  for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3561  iter != end;
3562  ++iter) {
3563  (*iter)(*this,obj);
3564  }
3565  }
3566 
3567  return 0;
3568 }
3569 
3570 ////////////////////////////////////////////////////////////////////////////////
3571 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3572 /// The collection needs to be a split TClonesArray or a split vector of pointers.
3573 
3574 Int_t TBufferFile::ApplySequenceVecPtr(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
3575 {
3576  if (gDebug) {
3577  //loop on all active members
3578  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3579  for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3580  iter != end;
3581  ++iter) {
3582  if (!start_collection || start_collection == end_collection)
3583  (*iter).PrintDebug(*this, nullptr); // Warning: This limits us to TClonesArray and vector of pointers.
3584  else
3585  (*iter).PrintDebug(*this, *(char**)start_collection); // Warning: This limits us to TClonesArray and vector of pointers.
3586  (*iter)(*this, start_collection, end_collection);
3587  }
3588 
3589  } else {
3590  //loop on all active members
3591  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3592  for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3593  iter != end;
3594  ++iter) {
3595  (*iter)(*this,start_collection,end_collection);
3596  }
3597  }
3598 
3599  return 0;
3600 }
3601 
3602 ////////////////////////////////////////////////////////////////////////////////
3603 /// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3604 
3605 Int_t TBufferFile::ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
3606 {
3608  if (gDebug) {
3609 
3610  // Get the address of the first item for the PrintDebug.
3611  // (Performance is not essential here since we are going to print to
3612  // the screen anyway).
3613  void *arr0 = start_collection ? loopconfig->GetFirstAddress(start_collection,end_collection) : 0;
3614  // loop on all active members
3615  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3616  for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3617  iter != end;
3618  ++iter) {
3619  (*iter).PrintDebug(*this,arr0);
3620  (*iter)(*this,start_collection,end_collection,loopconfig);
3621  }
3622 
3623  } else {
3624  //loop on all active members
3625  TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3626  for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3627  iter != end;
3628  ++iter) {
3629  (*iter)(*this,start_collection,end_collection,loopconfig);
3630  }
3631  }
3632 
3633  return 0;
3634 }
TStreamerInfo::Build
void Build()
Build the I/O data structure for the current class version.
Definition: TStreamerInfo.cxx:259
TClass::GetStreamerInfo
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:4567
c
#define c(i)
Definition: RSha256.hxx:101
l
auto * l
Definition: textangle.C:4
TBuffer::fParent
TObject * fParent
Definition: TBuffer.h:54
TBufferFile::ReadFastArrayString
void ReadFastArrayString(Char_t *c, Int_t n) override
Read array of n characters from the I/O buffer.
Definition: TBufferFile.cxx:1269
n
const Int_t n
Definition: legend1.C:16
TBufferFile::ReadFastArrayWithNbits
void ReadFastArrayWithNbits(Float_t *ptr, Int_t n, Int_t nbits) override
Read array of n floats (written as truncated float) from the I/O buffer.
Definition: TBufferFile.cxx:1468
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
frombufOld
static void frombufOld(char *&buf, Long_t *x)
Handle old file formats.
Definition: TBufferFile.cxx:143
TBufferFile::WriteVersion
UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE) override
Write class version to I/O buffer.
Definition: TBufferFile.cxx:2977
TBufferFile::ReadStaticArray
Int_t ReadStaticArray(Bool_t *b) override
Read array of bools from the I/O buffer.
Definition: TBufferFile.cxx:975
Version_t
short Version_t
Definition: RtypesCore.h:65
TClass::Streamer
void Streamer(void *obj, TBuffer &b, const TClass *onfile_class=0) const
Definition: TClass.h:559
TObjArray
An array of TObjects.
Definition: TObjArray.h:37
kNewClassTag
const UInt_t kNewClassTag
Definition: TBufferFile.cxx:48
f
#define f(i)
Definition: RSha256.hxx:104
kMaxMapCount
const UInt_t kMaxMapCount
Definition: TBufferFile.cxx:51
TBufferFile::WriteArrayFloat16
void WriteArrayFloat16(const Float_t *f, Int_t n, TStreamerElement *ele=nullptr) override
Write array of n floats (as truncated float) into the I/O buffer.
Definition: TBufferFile.cxx:1901
TStreamerInfo.h
TBufferFile::ReadFastArrayWithFactor
void ReadFastArrayWithFactor(Float_t *ptr, Int_t n, Double_t factor, Double_t minvalue) override
Read array of n floats (written as truncated float) from the I/O buffer.
Definition: TBufferFile.cxx:1454
TClass::Size
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5581
TBufferFile::ReadDouble32
void ReadDouble32(Double_t *d, TStreamerElement *ele=nullptr) override
Read a Double32_t from the buffer, see comments about Double32_t encoding at TBufferFile::WriteDouble...
Definition: TBufferFile.cxx:448
TBufferFile::ReadTString
void ReadTString(TString &s) override
Read TString from TBuffer.
Definition: TBufferFile.cxx:185
TBuffer::fBufCur
char * fBufCur
Definition: TBuffer.h:52
UShort_t
unsigned short UShort_t
Definition: RtypesCore.h:40
TList::FindObject
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:578
Class_Has_StreamerInfo
static bool Class_Has_StreamerInfo(const TClass *cl)
Thread-safe check on StreamerInfos of a TClass.
Definition: TBufferFile.cxx:62
kClassMask
const UInt_t kClassMask
Definition: TBufferFile.cxx:49
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TStreamerInfoActions.h
TClass::Property
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5915
bswapcpy32
void * bswapcpy32(void *to, const void *from, size_t n)
Definition: Bswapcpy.h:60
TBufferFile::WriteVersionMemberWise
UInt_t WriteVersionMemberWise(const TClass *cl, Bool_t useBcnt=kFALSE) override
Write class version to I/O buffer after setting the kStreamedMemberWise bit in the version number.
Definition: TBufferFile.cxx:3007
TBufferFile::CheckByteCount
Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss, const char *classname)
Check byte count with current buffer position.
Definition: TBufferFile.cxx:355
tobuf
void tobuf(char *&buf, Bool_t x)
Definition: Bytes.h:55
TStreamerElement.h
xmax
float xmax
Definition: THbookFile.cxx:95
TStreamerElement::GetXmax
Double_t GetXmax() const
Definition: TStreamerElement.h:127
TObject::Info
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:864
Long64_t
long long Long64_t
Definition: RtypesCore.h:73
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
bswapcpy16
void * bswapcpy16(void *to, const void *from, size_t n)
Definition: Bswapcpy.h:45
TBufferIO::WriteObjectAny
Int_t WriteObjectAny(const void *obj, const TClass *ptrClass, Bool_t cacheReuse=kTRUE) override
Write object to I/O buffer.
Definition: TBufferIO.cxx:492
TMemberStreamer::SetOnFileClass
virtual void SetOnFileClass(const TClass *cl)
Definition: TMemberStreamer.h:37
TBuffer::fBuffer
char * fBuffer
Definition: TBuffer.h:51
TBuffer::fVersion
Int_t fVersion
Definition: TBuffer.h:49
TStreamerInfoActions::TActionSequence::fActions
ActionContainer_t fActions
Definition: TStreamerInfoActions.h:193
TClass::HasDefaultConstructor
Bool_t HasDefaultConstructor(Bool_t testio=kFALSE) const
Return true if we have access to a constructor usable for I/O.
Definition: TClass.cxx:7196
TStreamerInfo::BuildEmulated
void BuildEmulated(TFile *file)
Create an Emulation TStreamerInfo object.
Definition: TStreamerInfo.cxx:1226
TBufferFile::WriteFastArray
void WriteFastArray(const Bool_t *b, Int_t n) override
Write array of n bools into the I/O buffer.
Definition: TBufferFile.cxx:1940
Float_t
float Float_t
Definition: RtypesCore.h:57
TClass::IsLoaded
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5789
TGeant4Unit::s
static constexpr double s
Definition: TGeant4SystemOfUnits.h:162
TBufferFile::WriteArray
void WriteArray(const Bool_t *b, Int_t n) override
Write array of n bools into the I/O buffer.
Definition: TBufferFile.cxx:1677
TBufferFile::ReadClass
TClass * ReadClass(const TClass *cl=nullptr, UInt_t *objTag=nullptr) override
Read class definition from I/O buffer.
Definition: TBufferFile.cxx:2565
Int_t
int Int_t
Definition: RtypesCore.h:45
TBufferFile::WriteFastArrayDouble32
void WriteFastArrayDouble32(const Double_t *d, Int_t n, TStreamerElement *ele=nullptr) override
Write array of n doubles (as float) into the I/O buffer.
Definition: TBufferFile.cxx:2184
TClass::GetClassVersion
Version_t GetClassVersion() const
Definition: TClass.h:381
x
Double_t x[n]
Definition: legend1.C:17
TBufferFile::ReadFastArrayDouble32
void ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele=nullptr) override
Read array of n doubles (written as float) from the I/O buffer.
Definition: TBufferFile.cxx:1496
TClass.h
TBufferIO::MapObject
void MapObject(const TObject *obj, UInt_t offset=1) override
Add object to the fMap container.
Definition: TBufferIO.cxx:163
ROOT::Detail::TSchemaRuleSet::HasRuleWithSourceClass
Bool_t HasRuleWithSourceClass(const TString &source) const
Return True if we have any rule whose source class is 'source'.
Definition: TSchemaRuleSet.cxx:198
TBuffer::fBufMax
char * fBufMax
Definition: TBuffer.h:53
ReAllocCharFun_t
char *(* ReAllocCharFun_t)(char *, size_t, size_t)
Definition: TStorage.h:30
TBufferFile::WriteObjectClass
void WriteObjectClass(const void *actualObjStart, const TClass *actualClass, Bool_t cacheReuse) override
Write object to I/O buffer.
Definition: TBufferFile.cxx:2488
kByteCountMask
const UInt_t kByteCountMask
Definition: TBufferFile.cxx:50
TStreamerElement::GetFactor
Double_t GetFactor() const
Definition: TStreamerElement.h:125
TBufferFile::ReadArrayFloat16
Int_t ReadArrayFloat16(Float_t *&f, TStreamerElement *ele=nullptr) override
Read array of floats (written as truncated float) from the I/O buffer.
Definition: TBufferFile.cxx:933
TStreamerInfo::GetWriteObjectWiseActions
TStreamerInfoActions::TActionSequence * GetWriteObjectWiseActions()
Definition: TStreamerInfo.h:218
TBufferFile::ReadArrayDouble32
Int_t ReadArrayDouble32(Double_t *&d, TStreamerElement *ele=nullptr) override
Read array of doubles (written as float) from the I/O buffer.
Definition: TBufferFile.cxx:955
TObjArray::UncheckedAt
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:90
TBufferFile::ReadString
char * ReadString(char *s, Int_t max) override
Read string from I/O buffer.
Definition: TBufferFile.cxx:3201
TBufferFile::WriteBuf
void WriteBuf(const void *buf, Int_t max) override
Write max bytes from buf into the I/O buffer.
Definition: TBufferFile.cxx:3183
TExMap::GetSize
Int_t GetSize() const
Definition: TExMap.h:71
TBufferFile::StreamObject
void StreamObject(void *obj, const std::type_info &typeinfo, const TClass *onFileClass=nullptr) override
Stream an object given its C++ typeinfo information.
Definition: TBufferFile.cxx:3038
TBufferIO::TagStreamerInfo
void TagStreamerInfo(TVirtualStreamerInfo *info) override
Mark the classindex of the current file as using this TStreamerInfo.
Definition: TBufferIO.cxx:350
TBufferIO::InitMap
void InitMap() override
Create the fMap container and initialize them with the null object.
Definition: TBufferIO.cxx:129
TBufferFile::ReadStdString
virtual void ReadStdString(std::string *s)=0
TExMap::GetValue
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition: TExMap.cxx:173
TString
Basic string class.
Definition: TString.h:136
TClass::GetSchemaRules
const ROOT::Detail::TSchemaRuleSet * GetSchemaRules() const
Return the set of the schema rules if any.
Definition: TClass.cxx:1896
TStreamer.h
Bool_t
bool Bool_t
Definition: RtypesCore.h:63
TClass::GetCheckSum
UInt_t GetCheckSum(ECheckSum code=kCurrentCheckSum) const
Call GetCheckSum with validity check.
Definition: TClass.cxx:6334
TClass::Load
static TClass * Load(TBuffer &b)
Load class description from I/O buffer and return class object.
Definition: TClass.cxx:5592
TBuffer::SetBufferOffset
void SetBufferOffset(Int_t offset=0)
Definition: TBuffer.h:93
TBufferFile::WriteTString
void WriteTString(const TString &s) override
Write TString to TBuffer.
Definition: TBufferFile.cxx:210
v
@ v
Definition: rootcling_impl.cxx:3635
b
#define b(i)
Definition: RSha256.hxx:100
TBufferFile::kStreamedMemberWise
@ kStreamedMemberWise
Definition: TBufferFile.h:69
kMaxVersion
const Version_t kMaxVersion
Definition: TBufferFile.cxx:53
TFile.h
TBufferFile::TBufferFile
TBufferFile()
Definition: TBufferFile.h:56
TVirtualStreamerInfo
Abstract Interface class describing Streamer information for one class.
Definition: TVirtualStreamerInfo.h:37
bool
TBufferFile::IncrementLevel
void IncrementLevel(TVirtualStreamerInfo *info) override
Increment level.
Definition: TBufferFile.cxx:119
TClass::FindStreamerInfo
TVirtualStreamerInfo * FindStreamerInfo(TObjArray *arr, UInt_t checksum) const
Find the TVirtualStreamerInfo in the StreamerInfos corresponding to checksum.
Definition: TClass.cxx:6890
TBufferFile::WriteClassBuffer
Int_t WriteClassBuffer(const TClass *cl, void *pointer) override
Function called by the Streamer functions to serialize object at p to buffer b.
Definition: TBufferFile.cxx:3502
TBufferFile::WriteCharStar
void WriteCharStar(char *s) override
Write char* into TBuffer.
Definition: TBufferFile.cxx:301
kByteCountVMask
const Version_t kByteCountVMask
Definition: TBufferFile.cxx:52
TClass::kEmulated
@ kEmulated
Definition: TClass.h:124
TObject::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
TStreamerInfo::Clear
void Clear(Option_t *)
If opt contains 'built', reset this StreamerInfo as if Build or BuildOld was never called on it (usef...
Definition: TStreamerInfo.cxx:2555
TStreamerInfo::GetReadObjectWiseActions
TStreamerInfoActions::TActionSequence * GetReadObjectWiseActions()
Definition: TStreamerInfo.h:215
TBufferFile::ReadVersionNoCheckSum
Version_t ReadVersionNoCheckSum(UInt_t *start=nullptr, UInt_t *bcnt=nullptr) override
Read class version from I/O buffer, when the caller knows for sure that there is no checksum written/...
Definition: TBufferFile.cxx:2866
TBufferFile::WriteDouble32
void WriteDouble32(Double_t *d, TStreamerElement *ele=nullptr) override
Write a Double32_t to the buffer.
Definition: TBufferFile.cxx:653
TBuffer::Length
Int_t Length() const
Definition: TBuffer.h:100
TBufferIO::kNullTag
@ kNullTag
Definition: TBufferIO.h:33
TClass::MatchLegacyCheckSum
Bool_t MatchLegacyCheckSum(UInt_t checksum) const
Return true if the checksum passed as argument is one of the checksum value produced by the older che...
Definition: TClass.cxx:6323
TObjArray::GetLast
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:577
TStreamerInfoActions::TActionSequence::fLoopConfig
TLoopConfiguration * fLoopConfig
If this is a bundle of memberwise streaming action, this configures the looping.
Definition: TStreamerInfoActions.h:192
TClass::InheritsFrom
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition: TClass.cxx:4835
TBufferFile::SkipVersion
void SkipVersion(const TClass *cl=nullptr) override
Skip class version from I/O buffer.
Definition: TBufferFile.cxx:2689
TBufferFile::WriteClass
void WriteClass(const TClass *cl) override
Write class description to I/O buffer.
Definition: TBufferFile.cxx:2651
TStreamerInfoActions::TLoopConfiguration::GetFirstAddress
virtual void * GetFirstAddress(void *start, const void *end) const =0
TBuffer::EMode
EMode
Definition: TBuffer.h:73
gInterpreterMutex
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:44
xmin
float xmin
Definition: THbookFile.cxx:95
TStreamerInfo
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:44
TClass::New
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4939
TBufferFile::ReadBuf
Int_t ReadBuf(void *buf, Int_t max) override
Read max bytes from the I/O buffer into buf.
Definition: TBufferFile.cxx:3166
h
#define h(i)
Definition: RSha256.hxx:106
TClass::IsForeign
Bool_t IsForeign() const
Return kTRUE is the class is Foreign (the class does not have a Streamer method).
Definition: TClass.cxx:5824
TBufferFile::ReadVersionForMemberWise
Version_t ReadVersionForMemberWise(const TClass *cl=nullptr) override
Read class version from I/O buffer.
Definition: TBufferFile.cxx:2909
TBuffer::IsWriting
Bool_t IsWriting() const
Definition: TBuffer.h:87
TClass::GetConversionStreamerInfo
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:6910
TStorage.h
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
Long_t
long Long_t
Definition: RtypesCore.h:54
TBufferFile::ReadObjectAny
void * ReadObjectAny(const TClass *cast) override
Read object from I/O buffer.
Definition: TBufferFile.cxx:2348
gDebug
Int_t gDebug
Definition: TROOT.cxx:590
Bswapcpy.h
TClass::GetStreamerInfos
const TObjArray * GetStreamerInfos() const
Definition: TClass.h:453
R__LOCKGUARD
#define R__LOCKGUARD(mutex)
Definition: TVirtualMutex.h:104
UInt_t
unsigned int UInt_t
Definition: RtypesCore.h:46
TBufferIO::fClassMap
TExMap * fClassMap
Map containing object,class pairs for reading.
Definition: TBufferIO.h:40
TClass::GetClass
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2932
ULong_t
unsigned long ULong_t
Definition: RtypesCore.h:55
TStreamerInfo::GetCheckSum
UInt_t GetCheckSum() const
Definition: TStreamerInfo.h:206
Short_t
short Short_t
Definition: RtypesCore.h:39
TBuffer::GetParent
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition: TBuffer.cxx:262
TBufferFile::WriteFastArrayString
void WriteFastArrayString(const Char_t *c, Int_t n) override
Write array of n characters into the I/O buffer.
Definition: TBufferFile.cxx:1973
TVirtualStreamerInfo::IsCompiled
Bool_t IsCompiled() const
Definition: TVirtualStreamerInfo.h:156
TBufferFile::fInfo
TStreamerInfo * fInfo
Pointer to TStreamerInfo object writing/reading the buffer.
Definition: TBufferFile.h:52
TBufferFile::ReadFastArrayFloat16
void ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele=nullptr) override
Read array of n floats (written as truncated float) from the I/O buffer.
Definition: TBufferFile.cxx:1414
TExMap::Capacity
Int_t Capacity() const
Definition: TExMap.h:69
TVirtualMutex.h
TObject::Warning
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:876
TBufferFile::ReadStaticArrayFloat16
Int_t ReadStaticArrayFloat16(Float_t *f, TStreamerElement *ele=nullptr) override
Read array of floats (written as truncated float) from the I/O buffer.
Definition: TBufferFile.cxx:1200
TFile
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition: TFile.h:54
TMath::Min
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:180
TBufferFile::ReadClassBuffer
Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class) override
Deserialize information from a buffer into an object.
Definition: TBufferFile.cxx:3360
unsigned int
TStreamerInfo::GetClassVersion
Int_t GetClassVersion() const
Definition: TStreamerInfo.h:208
TBufferIO
Direct subclass of TBuffer, implements common methods for TBufferFile and TBufferText classes.
Definition: TBufferIO.h:30
TBufferFile::ReadFastArray
void ReadFastArray(Bool_t *b, Int_t n) override
Read array of n bools from the I/O buffer.
Definition: TBufferFile.cxx:1240
TClass::GetCurrentStreamerInfo
TVirtualStreamerInfo * GetCurrentStreamerInfo()
Definition: TClass.h:400
TClass::GetLastReadInfo
TVirtualStreamerInfo * GetLastReadInfo() const
Definition: TClass.h:405
TBuffer::IsReading
Bool_t IsReading() const
Definition: TBuffer.h:86
TStreamerInfo::SetClassVersion
void SetClassVersion(Int_t vers)
Definition: TStreamerInfo.h:267
TBufferFile::WriteFloat16
void WriteFloat16(Float_t *f, TStreamerElement *ele=nullptr) override
Write a Float16_t to the buffer.
Definition: TBufferFile.cxx:589
Double_t
double Double_t
Definition: RtypesCore.h:59
TBuffer::fBufSize
Int_t fBufSize
Definition: TBuffer.h:50
TClass::SetLastReadInfo
void SetLastReadInfo(TVirtualStreamerInfo *info)
Definition: TClass.h:406
TBufferIO::fDisplacement
Int_t fDisplacement
Value to be added to the map offsets.
Definition: TBufferIO.h:37
R__ASSERT
#define R__ASSERT(e)
Definition: TError.h:120
TCollection::GetSize
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
TBufferFile::SetByteCount
void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE) override
Set byte count at position cntpos in the buffer.
Definition: TBufferFile.cxx:318
TBufferFile::ApplySequenceVecPtr
Int_t ApplySequenceVecPtr(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection) override
Read one collection of objects from the buffer using the StreamerInfoLoopAction.
Definition: TBufferFile.cxx:3574
TInterpreter.h
TClass
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:80
TBufferFile::ReadStaticArrayDouble32
Int_t ReadStaticArrayDouble32(Double_t *d, TStreamerElement *ele=nullptr) override
Read array of doubles (written as float) from the I/O buffer.
Definition: TBufferFile.cxx:1221
file
Definition: file.py:1
frombuf
void frombuf(char *&buf, Bool_t *x)
Definition: Bytes.h:278
TBufferFile::WriteFastArrayFloat16
void WriteFastArrayFloat16(const Float_t *f, Int_t n, TStreamerElement *ele=nullptr) override
Write array of n floats (as truncated float) into the I/O buffer.
Definition: TBufferFile.cxx:2133
UChar_t
unsigned char UChar_t
Definition: RtypesCore.h:38
TObject
Mother of all ROOT objects.
Definition: TObject.h:37
TBufferFile.h
TCollection::Capacity
Int_t Capacity() const
Definition: TCollection.h:165
TBufferFile::SkipObjectAny
void SkipObjectAny() override
Skip any kind of object from buffer.
Definition: TBufferFile.cxx:2328
TClass::GetBaseClassOffset
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2755
name
char name[80]
Definition: TGX11.cxx:110
TExMap::AddAt
void AddAt(UInt_t slot, ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table.
Definition: TExMap.cxx:116
TSchemaRuleSet.h
TStreamerInfo::BuildOld
void BuildOld()
rebuild the TStreamerInfo structure
Definition: TStreamerInfo.cxx:1666
TBufferFile::ReadCharStar
void ReadCharStar(char *&s) override
Read char* from TBuffer.
Definition: TBufferFile.cxx:284
TExMap::Remove
void Remove(ULong64_t hash, Long64_t key)
Remove entry with specified key from the TExMap.
Definition: TExMap.cxx:216
d
#define d(i)
Definition: RSha256.hxx:102
TClass::GetState
EState GetState() const
Definition: TClass.h:449
TBufferFile::WriteArrayDouble32
void WriteArrayDouble32(const Double_t *d, Int_t n, TStreamerElement *ele=nullptr) override
Write array of n doubles (as float) into the I/O buffer.
Definition: TBufferFile.cxx:1921
TBufferFile::ReadWithNbits
void ReadWithNbits(Float_t *ptr, Int_t nbits) override
Read a Float16_t from the buffer when the number of bits is specified (explicitly or not) see comment...
Definition: TBufferFile.cxx:482
TBufferFile::ReadClassEmulated
Int_t ReadClassEmulated(const TClass *cl, void *object, const TClass *onfile_class) override
Read emulated class.
Definition: TBufferFile.cxx:3236
kMaxInt
const Int_t kMaxInt
Definition: RtypesCore.h:103
TBufferFile::ApplySequence
Int_t ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *object) override
Read one collection of objects from the buffer using the StreamerInfoLoopAction.
Definition: TBufferFile.cxx:3545
TBufferFile::ReadFloat16
void ReadFloat16(Float_t *f, TStreamerElement *ele=nullptr) override
Read a Float16_t from the buffer, see comments about Float16_t encoding at TBufferFile::WriteFloat16(...
Definition: TBufferFile.cxx:432
TBuffer::AutoExpand
void AutoExpand(Int_t size_needed)
Automatically calculate a new size and expand the buffer to fit at least size_needed.
Definition: TBuffer.cxx:158
TBufferFile::CheckObject
Bool_t CheckObject(const TObject *obj) override
Check if the specified object is already in the buffer.
Definition: TBufferIO.cxx:225
TBufferIO::Void_Hash
static R__ALWAYS_INLINE ULong_t Void_Hash(const void *ptr)
Return hash value for provided object.
Definition: TBufferIO.h:53
TExMap::Add
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
Definition: TExMap.cxx:87
xmlio::cnt
const char * cnt
Definition: TXMLSetup.cxx:75
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TMemberStreamer
Definition: TMemberStreamer.h:26
TVirtualStreamerInfo::CanDelete
static Bool_t CanDelete()
static function returning true if ReadBuffer can delete object
Definition: TVirtualStreamerInfo.cxx:78
TStreamerInfoActions::TActionSequence
Definition: TStreamerInfoActions.h:172
TBufferFile::ReadWithFactor
void ReadWithFactor(Float_t *ptr, Double_t factor, Double_t minvalue) override
Read a Float16_t from the buffer when the factor and minimum value have been specified see comments a...
Definition: TBufferFile.cxx:470
TVirtualStreamerInfo::IsRecovered
Int_t IsRecovered() const
Definition: TVirtualStreamerInfo.h:158
TBufferFile::ReadLong
void ReadLong(Long_t &l) override
Read Long from TBuffer.
Definition: TBufferFile.cxx:172
kMapOffset
const Int_t kMapOffset
Definition: TBufferFile.cxx:54
TBufferFile::WriteStdString
virtual void WriteStdString(const std::string *s)=0
TBufferFile::ReadObject
TObject * ReadObject(const TClass *cl) override
Read object from I/O buffer.
Definition: TBufferFile.cxx:2320
TBufferFile::fInfoStack
InfoList_t fInfoStack
Stack of pointers to the TStreamerInfos.
Definition: TBufferFile.h:53
Char_t
char Char_t
Definition: RtypesCore.h:33
TBufferIO::fMapCount
Int_t fMapCount
Number of objects or classes in map.
Definition: TBufferIO.h:35
TBufferFile::ReadArray
Int_t ReadArray(Bool_t *&b) override
Read array of bools from the I/O buffer.
Definition: TBufferFile.cxx:700
TStreamerInfoActions::TLoopConfiguration
Base class of the Configurations for the member wise looping routines.
Definition: TStreamerInfoActions.h:53
TBufferFile
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
Definition: TBufferFile.h:47
TStreamerElement
Definition: TStreamerElement.h:33
TBufferFile::DecrementLevel
void DecrementLevel(TVirtualStreamerInfo *) override
Decrement level.
Definition: TBufferFile.cxx:128
TList
A doubly linked list.
Definition: TList.h:44
TBufferFile::ReadVersion
Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr) override
Read class version from I/O buffer.
Definition: TBufferFile.cxx:2760
TBufferIO::fMap
TExMap * fMap
Map containing object,offset pairs for reading/writing.
Definition: TBufferIO.h:39
TBufferFile::~TBufferFile
virtual ~TBufferFile()
Delete an I/O buffer object.
Definition: TBufferFile.cxx:112
TBufferFile::WriteString
void WriteString(const char *s) override
Write string to I/O buffer.
Definition: TBufferFile.cxx:3228
TStreamerElement::GetXmin
Double_t GetXmin() const
Definition: TStreamerElement.h:126
TExMap.h
int
TError.h
kIsAbstract
@ kIsAbstract
Definition: TDictionary.h:71
TBufferFile::CheckCount
void CheckCount(UInt_t offset) override
Check if offset is not too large (< kMaxMapCount) when writing.
Definition: TBufferFile.cxx:3074
TBufferIO::ForceWriteInfo
void ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t force) override
force writing the TStreamerInfo to the file
Definition: TBufferIO.cxx:329