Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
17The 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"
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
48const UInt_t kNewClassTag = 0xFFFFFFFF;
49const UInt_t kClassMask = 0x80000000; // OR the class index with this
50const UInt_t kByteCountMask = 0x40000000; // OR the byte count with this
51const UInt_t kMaxMapCount = 0x3FFFFFFE; // last valid fMapCount and byte count
52const Version_t kByteCountVMask = 0x4000; // OR the version byte count with this
53const Version_t kMaxVersion = 0x3FFF; // highest possible version number
54const 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
62static 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
103TBufferFile::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
143static 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) {
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
229void 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
260void 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
318void 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
355Int_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 Longptr_t endpos = Longptr_t(fBuffer) + startpos + bcnt + sizeof(UInt_t);
362
363 if (Longptr_t(fBufCur) != endpos) {
364 offset = Int_t(Longptr_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);
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
422Int_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{
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{
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{
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
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{
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{
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{
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{
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
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{
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{
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
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{
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{
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{
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{
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{
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{
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{
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{
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{
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{
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
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{
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
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
1595void 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
1618void 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{
1680
1681 *this << n;
1682
1683 if (n <= 0) return;
1684
1685 R__ASSERT(b);
1686
1687 Int_t l = sizeof(UChar_t)*n;
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{
1705
1706 *this << n;
1707
1708 if (n <= 0) return;
1709
1710 R__ASSERT(c);
1711
1712 Int_t l = sizeof(Char_t)*n;
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{
1725
1726 *this << n;
1727
1728 if (n <= 0) return;
1729
1730 R__ASSERT(h);
1731
1732 Int_t l = sizeof(Short_t)*n;
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{
1755
1756 *this << n;
1757
1758 if (n <= 0) return;
1759
1760 R__ASSERT(ii);
1761
1762 Int_t l = sizeof(Int_t)*n;
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{
1785
1786 *this << n;
1787
1788 if (n <= 0) return;
1789
1790 R__ASSERT(ll);
1791
1792 Int_t l = 8*n;
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{
1805
1806 *this << n;
1807
1808 if (n <= 0) return;
1809
1810 R__ASSERT(ll);
1811
1812 Int_t l = 8*n;
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{
1823
1824 *this << n;
1825
1826 if (n <= 0) return;
1827
1828 R__ASSERT(ll);
1829
1830 Int_t l = sizeof(Long64_t)*n;
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{
1848
1849 *this << n;
1850
1851 if (n <= 0) return;
1852
1853 R__ASSERT(f);
1854
1855 Int_t l = sizeof(Float_t)*n;
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{
1878
1879 *this << n;
1880
1881 if (n <= 0) return;
1882
1883 R__ASSERT(d);
1884
1885 Int_t l = sizeof(Double_t)*n;
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{
1904
1905 *this << n;
1906
1907 if (n <= 0) return;
1908
1909 R__ASSERT(f);
1910
1911 Int_t l = sizeof(Float_t)*n;
1913
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{
1924
1925 *this << n;
1926
1927 if (n <= 0) return;
1928
1929 R__ASSERT(d);
1930
1931 Int_t l = sizeof(Float_t)*n;
1933
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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;
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
2242void 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{
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 if (gDebug > 0)
2382 Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
2383 clOnfile = clRef;
2384 clRef = const_cast<TClass*>(clCast);
2385
2386 }
2387 if (clCast->GetState() > TClass::kEmulated && clRef->GetState() <= TClass::kEmulated) {
2388 //we cannot mix a compiled class with an emulated class in the inheritance
2389 Error("ReadObject", "trying to read an emulated class (%s) to store in a compiled pointer (%s)",
2390 clRef->GetName(),clCast->GetName());
2391 CheckByteCount(startpos, tag, (TClass *)nullptr); // avoid mis-leading byte count error message
2392 return 0;
2393 }
2394 }
2395
2396 // check if object has not already been read
2397 // (this can only happen when called via CheckObject())
2398 char *obj;
2399 if (fVersion > 0) {
2400 obj = (char *) (Longptr_t)fMap->GetValue(startpos+kMapOffset);
2401 if (obj == (void*) -1) obj = nullptr;
2402 if (obj) {
2403 CheckByteCount(startpos, tag, (TClass *)nullptr);
2404 return (obj + baseOffset);
2405 }
2406 }
2407
2408 // unknown class, skip to next object and return 0 obj
2409 if (clRef == (TClass*) -1) {
2410 if (fBufCur >= fBufMax) return 0;
2411 if (fVersion > 0)
2412 MapObject((TObject*) -1, startpos+kMapOffset);
2413 else
2414 MapObject((void*)nullptr, nullptr, fMapCount);
2415 CheckByteCount(startpos, tag, (TClass *)nullptr);
2416 return 0;
2417 }
2418
2419 if (!clRef) {
2420
2421 // got a reference to an already read object
2422 if (fVersion > 0) {
2423 tag += fDisplacement;
2424 tag = CheckObject(tag, clCast);
2425 } else {
2426 if (tag > (UInt_t)fMap->GetSize()) {
2427 Error("ReadObject", "object tag too large, I/O buffer corrupted");
2428 return 0;
2429 // exception
2430 }
2431 }
2432 obj = (char *) (Longptr_t)fMap->GetValue(tag);
2433 clRef = (TClass*) (Longptr_t)fClassMap->GetValue(tag);
2434
2435 if (clRef && (clRef!=(TClass*)(-1)) && clCast) {
2436 //baseOffset will be -1 if clRef does not inherit from clCast.
2437 baseOffset = clRef->GetBaseClassOffset(clCast);
2438 if (baseOffset == -1) {
2439 Error("ReadObject", "Got object of wrong class (Got %s while expecting %s)",
2440 clRef->GetName(),clCast->GetName());
2441 // exception
2442 baseOffset = 0;
2443 }
2444 }
2445
2446 // There used to be a warning printed here when:
2447 // obj && isTObject && !((TObject*)obj)->IsA()->InheritsFrom(clReq)
2448 // however isTObject was based on clReq (now clCast).
2449 // If the test was to fail, then it is as likely that the object is not a TObject
2450 // and then we have a potential core dump.
2451 // At this point (missing clRef), we do NOT have enough information to really
2452 // answer the question: is the object read of the type I requested.
2453
2454 } else {
2455
2456 // allocate a new object based on the class found
2457 obj = (char*)clRef->New();
2458 if (!obj) {
2459 Error("ReadObject", "could not create object of class %s",
2460 clRef->GetName());
2461 // exception
2462 return 0;
2463 }
2464
2465 // add to fMap before reading rest of object
2466 if (fVersion > 0)
2467 MapObject(obj, clRef, startpos+kMapOffset);
2468 else
2469 MapObject(obj, clRef, fMapCount);
2470
2471 // let the object read itself
2472 clRef->Streamer( obj, *this, clOnfile );
2473
2474 CheckByteCount(startpos, tag, clRef);
2475 }
2476
2477 return obj+baseOffset;
2478}
2479
2480////////////////////////////////////////////////////////////////////////////////
2481/// Write object to I/O buffer.
2482/// This function assumes that the value of 'actualObjectStart' is the actual start of
2483/// the object of class 'actualClass'
2484/// If 'cacheReuse' is true (default) upon seeing an object address a second time,
2485/// we record the offset where its was written the first time rather than streaming
2486/// the object a second time.
2487/// If 'cacheReuse' is false, we always stream the object. This allows the (re)use
2488/// of temporary object to store different data in the same buffer.
2489
2490void TBufferFile::WriteObjectClass(const void *actualObjectStart, const TClass *actualClass, Bool_t cacheReuse)
2491{
2493
2494 if (!actualObjectStart) {
2495
2496 // save kNullTag to represent NULL pointer
2497 *this << (UInt_t) kNullTag;
2498
2499 } else {
2500
2501 // make sure fMap is initialized
2502 InitMap();
2503
2504 ULongptr_t idx;
2505 UInt_t slot;
2506 ULong_t hash = Void_Hash(actualObjectStart);
2507
2508 if ((idx = (ULongptr_t)fMap->GetValue(hash, (Longptr_t)actualObjectStart, slot)) != 0) {
2509
2510 // truncation is OK the value we did put in the map is an 30-bit offset
2511 // and not a pointer
2512 UInt_t objIdx = UInt_t(idx);
2513
2514 // save index of already stored object
2515 *this << objIdx;
2516
2517 } else {
2518
2519 // A warning to let the user know it will need to change the class code
2520 // to be able to read this back.
2521 if (!actualClass->HasDefaultConstructor(kTRUE)) {
2522 Warning("WriteObjectAny", "since %s has no public constructor\n"
2523 "\twhich can be called without argument, objects of this class\n"
2524 "\tcan not be read with the current library. You will need to\n"
2525 "\tadd a default constructor before attempting to read it.",
2526 actualClass->GetName());
2527 }
2528
2529 // reserve space for leading byte count
2530 UInt_t cntpos = UInt_t(fBufCur-fBuffer);
2531 fBufCur += sizeof(UInt_t);
2532
2533 // write class of object first
2534 Int_t mapsize = fMap->Capacity(); // The slot depends on the capacity and WriteClass might induce an increase.
2535 WriteClass(actualClass);
2536
2537 if (cacheReuse) {
2538 // add to map before writing rest of object (to handle self reference)
2539 // (+kMapOffset so it's != kNullTag)
2540 //MapObject(actualObjectStart, actualClass, cntpos+kMapOffset);
2541 UInt_t offset = cntpos+kMapOffset;
2542 if (mapsize == fMap->Capacity()) {
2543 fMap->AddAt(slot, hash, (Longptr_t)actualObjectStart, offset);
2544 } else {
2545 // The slot depends on the capacity and WriteClass has induced an increase.
2546 fMap->Add(hash, (Longptr_t)actualObjectStart, offset);
2547 }
2548 // No need to keep track of the class in write mode
2549 // fClassMap->Add(hash, (Long_t)obj, (Long_t)((TObject*)obj)->IsA());
2550 fMapCount++;
2551 }
2552
2553 ((TClass*)actualClass)->Streamer((void*)actualObjectStart,*this);
2554
2555 // write byte count
2556 SetByteCount(cntpos);
2557 }
2558 }
2559}
2560
2561////////////////////////////////////////////////////////////////////////////////
2562/// Read class definition from I/O buffer.
2563///
2564/// \param[in] clReq Can be used to cross check if the actually read object is of the requested class.
2565/// \param[in] objTag Set in case the object is a reference to an already read object.
2566
2568{
2570
2571 // read byte count and/or tag (older files don't have byte count)
2572 TClass *cl;
2573 if (fBufCur < fBuffer || fBufCur > fBufMax) {
2574 fBufCur = fBufMax;
2575 cl = (TClass*)-1;
2576 return cl;
2577 }
2578 UInt_t bcnt, tag, startpos = 0;
2579 *this >> bcnt;
2580 if (!(bcnt & kByteCountMask) || bcnt == kNewClassTag) {
2581 tag = bcnt;
2582 bcnt = 0;
2583 } else {
2584 fVersion = 1;
2585 startpos = UInt_t(fBufCur-fBuffer);
2586 *this >> tag;
2587 }
2588
2589 // in case tag is object tag return tag
2590 if (!(tag & kClassMask)) {
2591 if (objTag) *objTag = tag;
2592 return 0;
2593 }
2594
2595 if (tag == kNewClassTag) {
2596
2597 // got a new class description followed by a new object
2598 // (class can be 0 if class dictionary is not found, in that
2599 // case object of this class must be skipped)
2600 cl = TClass::Load(*this);
2601
2602 // add class to fMap for later reference
2603 if (fVersion > 0) {
2604 // check if class was already read
2605 TClass *cl1 = (TClass *)(Longptr_t)fMap->GetValue(startpos+kMapOffset);
2606 if (cl1 != cl)
2607 MapObject(cl ? cl : (TObject*) -1, startpos+kMapOffset);
2608 } else
2609 MapObject(cl, fMapCount);
2610
2611 } else {
2612
2613 // got a tag to an already seen class
2614 UInt_t clTag = (tag & ~kClassMask);
2615
2616 if (fVersion > 0) {
2617 clTag += fDisplacement;
2618 clTag = CheckObject(clTag, clReq, kTRUE);
2619 } else {
2620 if (clTag == 0 || clTag > (UInt_t)fMap->GetSize()) {
2621 Error("ReadClass", "illegal class tag=%d (0<tag<=%d), I/O buffer corrupted",
2622 clTag, fMap->GetSize());
2623 // exception
2624 }
2625 }
2626
2627 // class can be 0 if dictionary was not found
2628 cl = (TClass *)(Longptr_t)fMap->GetValue(clTag);
2629 }
2630
2631 if (cl && clReq &&
2632 (!cl->InheritsFrom(clReq) &&
2633 !(clReq->GetSchemaRules() &&
2635 ) ) {
2636 Error("ReadClass", "The on-file class is \"'%s\" which is not compatible with the requested class: \"%s\"",
2637 cl->GetName(), clReq->GetName());
2638 // exception
2639 }
2640
2641 // return bytecount in objTag
2642 if (objTag) *objTag = (bcnt & ~kByteCountMask);
2643
2644 // case of unknown class
2645 if (!cl) cl = (TClass*)-1;
2646
2647 return cl;
2648}
2649
2650////////////////////////////////////////////////////////////////////////////////
2651/// Write class description to I/O buffer.
2652
2654{
2656
2657 ULongptr_t idx;
2658 ULong_t hash = Void_Hash(cl);
2659 UInt_t slot;
2660
2661 if ((idx = (ULongptr_t)fMap->GetValue(hash, (Longptr_t)cl,slot)) != 0) {
2662
2663 // truncation is OK the value we did put in the map is an 30-bit offset
2664 // and not a pointer
2665 UInt_t clIdx = UInt_t(idx);
2666
2667 // save index of already stored class
2668 *this << (clIdx | kClassMask);
2669
2670 } else {
2671
2672 // offset in buffer where class info is written
2673 UInt_t offset = UInt_t(fBufCur-fBuffer);
2674
2675 // save new class tag
2676 *this << kNewClassTag;
2677
2678 // write class name
2679 cl->Store(*this);
2680
2681 // store new class reference in fMap (+kMapOffset so it's != kNullTag)
2682 CheckCount(offset+kMapOffset);
2683 fMap->AddAt(slot, hash, (Longptr_t)cl, offset+kMapOffset);
2684 fMapCount++;
2685 }
2686}
2687
2688////////////////////////////////////////////////////////////////////////////////
2689/// Skip class version from I/O buffer.
2690
2692{
2693 Version_t version;
2694
2695 // not interested in byte count
2696 frombuf(this->fBufCur,&version);
2697
2698 // if this is a byte count, then skip next short and read version
2699 if (version & kByteCountVMask) {
2700 frombuf(this->fBufCur,&version);
2701 frombuf(this->fBufCur,&version);
2702 }
2703
2704 if (cl && cl->GetClassVersion() != 0 && version<=1) {
2705 if (version <= 0) {
2706 UInt_t checksum = 0;
2707 //*this >> checksum;
2708 frombuf(this->fBufCur,&checksum);
2709 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2710 if (vinfo) {
2711 return;
2712 } else {
2713 // There are some cases (for example when the buffer was stored outside of
2714 // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2715 // the one from the current class, we can still assume that we can read
2716 // the data so let use it.
2717 if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2718 version = cl->GetClassVersion();
2719 } else {
2720 if (fParent) {
2721 Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
2722 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2723 } else {
2724 Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" (buffer with no parent)",
2725 checksum, cl->GetName());
2726 }
2727 return;
2728 }
2729 }
2730 } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 ) {
2731 // We could have a file created using a Foreign class before
2732 // the introduction of the CheckSum. We need to check
2733 if ((!cl->IsLoaded() || cl->IsForeign()) &&
2735
2736 const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2737 const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2738 if ( local ) {
2739 UInt_t checksum = local->GetCheckSum();
2740 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2741 if (vinfo) {
2742 version = vinfo->GetClassVersion();
2743 } else {
2744 Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
2745 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2746 return;
2747 }
2748 }
2749 else {
2750 Error("SkipVersion", "Class %s not known to file %s.",
2751 cl->GetName(), ((TFile*)fParent)->GetName());
2752 version = 0;
2753 }
2754 }
2755 }
2756 }
2757}
2758
2759////////////////////////////////////////////////////////////////////////////////
2760/// Read class version from I/O buffer.
2761
2763{
2764 Version_t version;
2765
2766 if (startpos) {
2767 // before reading object save start position
2768 *startpos = UInt_t(fBufCur-fBuffer);
2769 }
2770
2771 // read byte count (older files don't have byte count)
2772 // byte count is packed in two individual shorts, this to be
2773 // backward compatible with old files that have at this location
2774 // only a single short (i.e. the version)
2775 union {
2776 UInt_t cnt;
2777 Version_t vers[2];
2778 } v;
2779#ifdef R__BYTESWAP
2780 frombuf(this->fBufCur,&v.vers[1]);
2781 frombuf(this->fBufCur,&v.vers[0]);
2782#else
2783 frombuf(this->fBufCur,&v.vers[0]);
2784 frombuf(this->fBufCur,&v.vers[1]);
2785#endif
2786
2787 // no bytecount, backup and read version
2788 if (!(v.cnt & kByteCountMask)) {
2789 fBufCur -= sizeof(UInt_t);
2790 v.cnt = 0;
2791 }
2792 if (bcnt) *bcnt = (v.cnt & ~kByteCountMask);
2793 frombuf(this->fBufCur,&version);
2794
2795 if (version<=1) {
2796 if (version <= 0) {
2797 if (cl) {
2798 if (cl->GetClassVersion() != 0
2799 // If v.cnt < 6 then we have a class with a version that used to be zero and so there is no checksum.
2800 && (v.cnt && v.cnt >= 6)
2801 ) {
2802 UInt_t checksum = 0;
2803 //*this >> checksum;
2804 frombuf(this->fBufCur,&checksum);
2805 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2806 if (vinfo) {
2807 return vinfo->TStreamerInfo::GetClassVersion(); // Try to get inlining.
2808 } else {
2809 // There are some cases (for example when the buffer was stored outside of
2810 // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2811 // the one from the current class, we can still assume that we can read
2812 // the data so let use it.
2813 if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2814 version = cl->GetClassVersion();
2815 } else {
2816 if (fParent) {
2817 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" in %s.",
2818 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2819 } else {
2820 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" (buffer with no parent)",
2821 checksum, cl->GetName());
2822 }
2823 return 0;
2824 }
2825 }
2826 }
2827 } else { // of if (cl) {
2828 UInt_t checksum = 0;
2829 //*this >> checksum;
2830 // If *bcnt < 6 then we have a class with 'just' version zero and no checksum
2831 if (v.cnt && v.cnt >= 6)
2832 frombuf(this->fBufCur,&checksum);
2833 }
2834 } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 && cl && cl->GetClassVersion() != 0) {
2835 // We could have a file created using a Foreign class before
2836 // the introduction of the CheckSum. We need to check
2837 if ((!cl->IsLoaded() || cl->IsForeign()) &&
2839
2840 const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2841 const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2842 if ( local ) {
2843 UInt_t checksum = local->GetCheckSum();
2844 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2845 if (vinfo) {
2846 version = vinfo->GetClassVersion();
2847 } else {
2848 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" in %s.",
2849 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2850 return 0;
2851 }
2852 }
2853 else {
2854 Error("ReadVersion", "Class %s not known to file %s.",
2855 cl->GetName(), ((TFile*)fParent)->GetName());
2856 version = 0;
2857 }
2858 }
2859 }
2860 }
2861 return version;
2862}
2863
2864////////////////////////////////////////////////////////////////////////////////
2865/// Read class version from I/O buffer, when the caller knows for sure that
2866/// there is no checksum written/involved.
2867
2869{
2870 Version_t version;
2871
2872 if (startpos) {
2873 // before reading object save start position
2874 *startpos = UInt_t(fBufCur-fBuffer);
2875 }
2876
2877 // read byte count (older files don't have byte count)
2878 // byte count is packed in two individual shorts, this to be
2879 // backward compatible with old files that have at this location
2880 // only a single short (i.e. the version)
2881 union {
2882 UInt_t cnt;
2883 Version_t vers[2];
2884 } v;
2885#ifdef R__BYTESWAP
2886 frombuf(this->fBufCur,&v.vers[1]);
2887 frombuf(this->fBufCur,&v.vers[0]);
2888#else
2889 frombuf(this->fBufCur,&v.vers[0]);
2890 frombuf(this->fBufCur,&v.vers[1]);
2891#endif
2892
2893 // no bytecount, backup and read version
2894 if (!(v.cnt & kByteCountMask)) {
2895 fBufCur -= sizeof(UInt_t);
2896 v.cnt = 0;
2897 }
2898 if (bcnt) *bcnt = (v.cnt & ~kByteCountMask);
2899 frombuf(this->fBufCur,&version);
2900
2901 return version;
2902}
2903
2904////////////////////////////////////////////////////////////////////////////////
2905/// Read class version from I/O buffer
2906///
2907/// To be used when streaming out member-wise streamed collection where we do not
2908/// care (not save) about the byte count and can safely ignore missing streamerInfo
2909/// (since they usually indicate empty collections).
2910
2912{
2913 Version_t version;
2914
2915 // not interested in byte count
2916 frombuf(this->fBufCur,&version);
2917
2918 if (version<=1) {
2919 if (version <= 0) {
2920 if (cl) {
2921 if (cl->GetClassVersion() != 0) {
2922 UInt_t checksum = 0;
2923 frombuf(this->fBufCur,&checksum);
2924 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2925 if (vinfo) {
2926 return vinfo->TStreamerInfo::GetClassVersion(); // Try to get inlining.
2927 } else {
2928 // There are some cases (for example when the buffer was stored outside of
2929 // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2930 // the one from the current class, we can still assume that we can read
2931 // the data so let use it.
2932 if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2933 version = cl->GetClassVersion();
2934 } else {
2935 // If we can not find the streamerInfo this means that
2936 // we do not actually need it (the collection is always empty
2937 // in this file), so no need to issue a warning.
2938 return 0;
2939 }
2940 }
2941 }
2942 } else { // of if (cl) {
2943 UInt_t checksum = 0;
2944 frombuf(this->fBufCur,&checksum);
2945 }
2946 } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 && cl && cl->GetClassVersion() != 0) {
2947 // We could have a file created using a Foreign class before
2948 // the introduction of the CheckSum. We need to check
2949 if ((!cl->IsLoaded() || cl->IsForeign()) && Class_Has_StreamerInfo(cl) ) {
2950
2951 const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2952 const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2953 if ( local ) {
2954 UInt_t checksum = local->GetCheckSum();
2955 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2956 if (vinfo) {
2957 version = vinfo->GetClassVersion();
2958 } else {
2959 // If we can not find the streamerInfo this means that
2960 // we do not actually need it (the collection is always empty
2961 // in this file), so no need to issue a warning.
2962 return 0;
2963 }
2964 }
2965 else {
2966 Error("ReadVersion", "Class %s not known to file %s.",
2967 cl->GetName(), ((TFile*)fParent)->GetName());
2968 version = 0;
2969 }
2970 }
2971 }
2972 }
2973 return version;
2974}
2975
2976////////////////////////////////////////////////////////////////////////////////
2977/// Write class version to I/O buffer.
2978
2980{
2981 UInt_t cntpos = 0;
2982 if (useBcnt) {
2983 // reserve space for leading byte count
2984 cntpos = UInt_t(fBufCur-fBuffer);
2985 fBufCur += sizeof(UInt_t);
2986 }
2987
2988 Version_t version = cl->GetClassVersion();
2989 if (version<=1 && cl->IsForeign()) {
2990 *this << Version_t(0);
2991 *this << cl->GetCheckSum();
2992 } else {
2993 if (version > kMaxVersion) {
2994 Error("WriteVersion", "version number cannot be larger than %hd)",
2995 kMaxVersion);
2996 version = kMaxVersion;
2997 }
2998 *this <<version;
2999 }
3000
3001 // return position where to store possible byte count
3002 return cntpos;
3003}
3004
3005////////////////////////////////////////////////////////////////////////////////
3006/// Write class version to I/O buffer after setting the kStreamedMemberWise
3007/// bit in the version number.
3008
3010{
3011 UInt_t cntpos = 0;
3012 if (useBcnt) {
3013 // reserve space for leading byte count
3014 cntpos = UInt_t(fBufCur-fBuffer);
3015 fBufCur += sizeof(UInt_t);
3016 }
3017
3018 Version_t version = cl->GetClassVersion();
3019 if (version<=1 && cl->IsForeign()) {
3020 Error("WriteVersionMemberWise", "Member-wise streaming of foreign collection not yet implemented!");
3021 *this << Version_t(0);
3022 *this << cl->GetCheckSum();
3023 } else {
3024 if (version > kMaxVersion) {
3025 Error("WriteVersionMemberWise", "version number cannot be larger than %hd)",
3026 kMaxVersion);
3027 version = kMaxVersion;
3028 }
3029 version |= kStreamedMemberWise;
3030 *this <<version;
3031 }
3032
3033 // return position where to store possible byte count
3034 return cntpos;
3035}
3036
3037////////////////////////////////////////////////////////////////////////////////
3038/// Stream an object given its C++ typeinfo information.
3039
3040void TBufferFile::StreamObject(void *obj, const std::type_info &typeinfo, const TClass* onFileClass )
3041{
3042 TClass *cl = TClass::GetClass(typeinfo);
3043 if (cl) cl->Streamer(obj, *this, (TClass*)onFileClass );
3044 else Warning("StreamObject","No TClass for the type %s is available, the object was not read.", typeinfo.name());
3045}
3046
3047////////////////////////////////////////////////////////////////////////////////
3048/// Stream an object given the name of its actual class.
3049
3050void TBufferFile::StreamObject(void *obj, const char *className, const TClass* onFileClass)
3051{
3052 TClass *cl = TClass::GetClass(className);
3053 if (cl) cl->Streamer(obj, *this, (TClass*)onFileClass );
3054 else Warning("StreamObject","No TClass for the type %s is available, the object was not read.", className);
3055}
3056
3057////////////////////////////////////////////////////////////////////////////////
3058/// Stream an object given a pointer to its actual class.
3059
3060void TBufferFile::StreamObject(void *obj, const TClass *cl, const TClass* onFileClass )
3061{
3062 ((TClass*)cl)->Streamer(obj, *this, (TClass*)onFileClass );
3063}
3064
3065////////////////////////////////////////////////////////////////////////////////
3066/// Stream an object inheriting from TObject using its streamer.
3067
3069{
3070 obj->Streamer(*this);
3071}
3072
3073////////////////////////////////////////////////////////////////////////////////
3074/// Check if offset is not too large (< kMaxMapCount) when writing.
3075
3077{
3078 if (IsWriting()) {
3079 if (offset >= kMaxMapCount) {
3080 Error("CheckCount", "buffer offset too large (larger than %d)", kMaxMapCount);
3081 // exception
3082 }
3083 }
3084}
3085
3086////////////////////////////////////////////////////////////////////////////////
3087/// Check for object in the read map. If the object is 0 it still has to be
3088/// read. Try to read it from the buffer starting at location offset. If the
3089/// object is -1 then it really does not exist and we return 0. If the object
3090/// exists just return the offset.
3091
3093{
3094 // in position 0 we always have the reference to the null object
3095 if (!offset) return offset;
3096
3097 Longptr_t cli;
3098
3099 if (readClass) {
3100 if ((cli = fMap->GetValue(offset)) == 0) {
3101 // No class found at this location in map. It might have been skipped
3102 // as part of a skipped object. Try to explicitly read the class.
3103
3104 // save fBufCur and set to place specified by offset (-kMapOffset-sizeof(bytecount))
3105 char *bufsav = fBufCur;
3106 fBufCur = (char *)(fBuffer + offset-kMapOffset-sizeof(UInt_t));
3107
3108 TClass *c = ReadClass(cl);
3109 if (c == (TClass*) -1) {
3110 // mark class as really not available
3111 fMap->Remove(offset);
3112 fMap->Add(offset, -1);
3113 offset = 0;
3114 if (cl)
3115 Warning("CheckObject", "reference to unavailable class %s,"
3116 " pointers of this type will be 0", cl->GetName());
3117 else
3118 Warning("CheckObject", "reference to an unavailable class,"
3119 " pointers of that type will be 0");
3120 }
3121
3122 fBufCur = bufsav;
3123
3124 } else if (cli == -1) {
3125
3126 // class really does not exist
3127 return 0;
3128 }
3129
3130 } else {
3131
3132 if ((cli = fMap->GetValue(offset)) == 0) {
3133 // No object found at this location in map. It might have been skipped
3134 // as part of a skipped object. Try to explicitly read the object.
3135
3136 // save fBufCur and set to place specified by offset (-kMapOffset)
3137 char *bufsav = fBufCur;
3138 fBufCur = (char *)(fBuffer + offset-kMapOffset);
3139
3140 TObject *obj = ReadObject(cl);
3141 if (!obj) {
3142 // mark object as really not available
3143 fMap->Remove(offset);
3144 fMap->Add(offset, -1);
3145 Warning("CheckObject", "reference to object of unavailable class %s, offset=%d"
3146 " pointer will be 0", cl ? cl->GetName() : "TObject",offset);
3147 offset = 0;
3148 }
3149
3150 fBufCur = bufsav;
3151
3152 } else if (cli == -1) {
3153
3154 // object really does not exist
3155 return 0;
3156 }
3157
3158 }
3159
3160 return offset;
3161}
3162
3163
3164////////////////////////////////////////////////////////////////////////////////
3165/// Read max bytes from the I/O buffer into buf. The function returns
3166/// the actual number of bytes read.
3167
3169{
3171
3172 if (max == 0) return 0;
3173
3174 Int_t n = TMath::Min(max, (Int_t)(fBufMax - fBufCur));
3175
3176 memcpy(buf, fBufCur, n);
3177 fBufCur += n;
3178
3179 return n;
3180}
3181
3182////////////////////////////////////////////////////////////////////////////////
3183/// Write max bytes from buf into the I/O buffer.
3184
3185void TBufferFile::WriteBuf(const void *buf, Int_t max)
3186{
3188
3189 if (max == 0) return;
3190
3191 if (fBufCur + max > fBufMax) AutoExpand(fBufSize+max); // a more precise request would be: fBufSize + max - (fBufMax - fBufCur)
3192
3193 memcpy(fBufCur, buf, max);
3194 fBufCur += max;
3195}
3196
3197////////////////////////////////////////////////////////////////////////////////
3198/// Read string from I/O buffer. String is read till 0 character is
3199/// found or till max-1 characters are read (i.e. string s has max
3200/// bytes allocated). If max = -1 no check on number of character is
3201/// made, reading continues till 0 character is found.
3202
3204{
3206
3207 char ch;
3208 Int_t nr = 0;
3209
3210 if (max == -1) max = kMaxInt;
3211
3212 while (nr < max-1) {
3213
3214 *this >> ch;
3215
3216 // stop when 0 read
3217 if (ch == 0) break;
3218
3219 s[nr++] = ch;
3220 }
3221
3222 s[nr] = 0;
3223 return s;
3224}
3225
3226////////////////////////////////////////////////////////////////////////////////
3227/// Write string to I/O buffer. Writes string upto and including the
3228/// terminating 0.
3229
3230void TBufferFile::WriteString(const char *s)
3231{
3232 WriteBuf(s, (strlen(s)+1)*sizeof(char));
3233}
3234
3235////////////////////////////////////////////////////////////////////////////////
3236/// Read emulated class.
3237
3238Int_t TBufferFile::ReadClassEmulated(const TClass *cl, void *object, const TClass *onFileClass)
3239{
3240 UInt_t start,count;
3241 //We assume that the class was written with a standard streamer
3242 //We attempt to recover if a version count was not written
3243 Version_t v = ReadVersion(&start,&count);
3244
3245 if (count) {
3246 TStreamerInfo *sinfo = nullptr;
3247 if( onFileClass ) {
3248 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, v );
3249 if( !sinfo )
3250 return 0;
3251 }
3252
3253 sinfo = (TStreamerInfo*)cl->GetStreamerInfo(v);
3254 ApplySequence(*(sinfo->GetReadObjectWiseActions()), object);
3255 if (sinfo->IsRecovered()) count=0;
3256 CheckByteCount(start,count,cl);
3257 } else {
3258 SetBufferOffset(start);
3259 TStreamerInfo *sinfo = ((TStreamerInfo*)cl->GetStreamerInfo());
3260 ApplySequence(*(sinfo->GetReadObjectWiseActions()), object);
3261 }
3262 return 0;
3263}
3264
3265////////////////////////////////////////////////////////////////////////////////
3266/// Deserialize information from a buffer into an object.
3267///
3268/// Note: This function is called by the xxx::Streamer() functions in
3269/// rootcint-generated dictionaries.
3270/// This function assumes that the class version and the byte count
3271/// information have been read.
3272///
3273/// \param[in] version The version number of the class
3274/// \param[in] start The starting position in the buffer b
3275/// \param[in] count The number of bytes for this object in the buffer
3276///
3277
3278Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, Int_t version, UInt_t start, UInt_t count, const TClass *onFileClass)
3279{
3280
3281 //---------------------------------------------------------------------------
3282 // The ondisk class has been specified so get foreign streamer info
3283 /////////////////////////////////////////////////////////////////////////////
3284
3285 TStreamerInfo *sinfo = nullptr;
3286 if( onFileClass ) {
3287 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, version );
3288 if( !sinfo ) {
3289 Error("ReadClassBuffer",
3290 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
3291 onFileClass->GetName(), version, cl->GetName(), Length() );
3292 CheckByteCount(start, count, onFileClass);
3293 return 0;
3294 }
3295 }
3296 //---------------------------------------------------------------------------
3297 // Get local streamer info
3298 /////////////////////////////////////////////////////////////////////////////
3299 /// The StreamerInfo should exist at this point.
3300
3301 else {
3303 auto infos = cl->GetStreamerInfos();
3304 auto ninfos = infos->GetSize();
3305 if (version < -1 || version >= ninfos) {
3306 Error("ReadClassBuffer", "class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
3307 cl->GetName(), version, Length() );
3308 CheckByteCount(start, count, cl);
3309 return 0;
3310 }
3311 sinfo = (TStreamerInfo*)infos->At(version);
3312 if (sinfo == nullptr) {
3313 // Unless the data is coming via a socket connection from with schema evolution
3314 // (tracking) was not enabled. So let's create the StreamerInfo if it is the
3315 // one for the current version, otherwise let's complain ...
3316 // We could also get here if there old class version was '1' and the new class version is higher than 1
3317 // AND the checksum is the same.
3319 // check if another thread took care of this already
3320 sinfo = (TStreamerInfo*)cl->GetStreamerInfos()->At(version);
3321 if (sinfo == nullptr) {
3322 if ( version == cl->GetClassVersion() || version == 1 ) {
3323 const_cast<TClass*>(cl)->BuildRealData(pointer);
3324 // This creation is alright since we just checked within the
3325 // current 'locked' section.
3326 sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
3327 const_cast<TClass*>(cl)->RegisterStreamerInfo(sinfo);
3328 if (gDebug > 0) Info("ReadClassBuffer", "Creating StreamerInfo for class: %s, version: %d", cl->GetName(), version);
3329 sinfo->Build();
3330 } else if (version==0) {
3331 // When the object was written the class was version zero, so
3332 // there is no StreamerInfo to be found.
3333 // Check that the buffer position corresponds to the byte count.
3334 CheckByteCount(start, count, cl);
3335 return 0;
3336 } else {
3337 Error("ReadClassBuffer", "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
3338 version, cl->GetName(), Length() );
3339 CheckByteCount(start, count, cl);
3340 return 0;
3341 }
3342 }
3343 } else if (!sinfo->IsCompiled()) { // Note this read is protected by the above lock.
3344 // Streamer info has not been compiled, but exists.
3345 // Therefore it was read in from a file and we have to do schema evolution.
3347 // check if another thread took care of this already
3348 if (!sinfo->IsCompiled()) {
3349 const_cast<TClass*>(cl)->BuildRealData(pointer);
3350 sinfo->BuildOld();
3351 }
3352 }
3353 }
3354
3355 // Deserialize the object.
3356 ApplySequence(*(sinfo->GetReadObjectWiseActions()), (char*)pointer);
3357 if (sinfo->IsRecovered()) count=0;
3358
3359 // Check that the buffer position corresponds to the byte count.
3360 CheckByteCount(start, count, cl);
3361 return 0;
3362}
3363
3364////////////////////////////////////////////////////////////////////////////////
3365/// Deserialize information from a buffer into an object.
3366///
3367/// Note: This function is called by the xxx::Streamer()
3368/// functions in rootcint-generated dictionaries.
3369///
3370
3371Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onFileClass)
3372{
3373 // Read the class version from the buffer.
3374 UInt_t R__s = 0; // Start of object.
3375 UInt_t R__c = 0; // Count of bytes.
3376 Version_t version;
3377
3378 if( onFileClass )
3379 version = ReadVersion(&R__s, &R__c, onFileClass);
3380 else
3381 version = ReadVersion(&R__s, &R__c, cl);
3382
3383 Bool_t v2file = kFALSE;
3384 TFile *file = (TFile*)GetParent();
3385 if (file && file->GetVersion() < 30000) {
3386 version = -1; //This is old file
3387 v2file = kTRUE;
3388 }
3389
3390 //---------------------------------------------------------------------------
3391 // The ondisk class has been specified so get foreign streamer info
3392 /////////////////////////////////////////////////////////////////////////////
3393
3394 TStreamerInfo *sinfo = nullptr;
3395 if( onFileClass ) {
3396 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, version );
3397 if( !sinfo ) {
3398 Error("ReadClassBuffer",
3399 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
3400 onFileClass->GetName(), version, cl->GetName(), Length() );
3401 CheckByteCount(R__s, R__c, onFileClass);
3402 return 0;
3403 }
3404 }
3405 //---------------------------------------------------------------------------
3406 // Get local streamer info
3407 /////////////////////////////////////////////////////////////////////////////
3408 /// The StreamerInfo should exist at this point.
3409
3410 else {
3412 if (guess && guess->GetClassVersion() == version) {
3413 sinfo = guess;
3414 } else {
3415 // The last one is not the one we are looking for.
3416 {
3418
3419 const TObjArray *infos = cl->GetStreamerInfos();
3420 Int_t infocapacity = infos->Capacity();
3421 if (infocapacity) {
3422 if (version < -1 || version >= infocapacity) {
3423 Error("ReadClassBuffer","class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
3424 cl->GetName(), version, Length());
3425 CheckByteCount(R__s, R__c, cl);
3426 return 0;
3427 }
3428 sinfo = (TStreamerInfo*) infos->UncheckedAt(version);
3429 if (sinfo) {
3430 if (!sinfo->IsCompiled())
3431 {
3432 // Streamer info has not been compiled, but exists.
3433 // Therefore it was read in from a file and we have to do schema evolution?
3435 const_cast<TClass*>(cl)->BuildRealData(pointer);
3436 sinfo->BuildOld();
3437 }
3438 // If the compilation succeeded, remember this StreamerInfo.
3439 // const_cast okay because of the lock on gInterpreterMutex.
3440 if (sinfo->IsCompiled()) const_cast<TClass*>(cl)->SetLastReadInfo(sinfo);
3441 }
3442 }
3443 }
3444
3445 if (sinfo == nullptr) {
3446 // Unless the data is coming via a socket connection from with schema evolution
3447 // (tracking) was not enabled. So let's create the StreamerInfo if it is the
3448 // one for the current version, otherwise let's complain ...
3449 // We could also get here when reading a file prior to the introduction of StreamerInfo.
3450 // We could also get here if there old class version was '1' and the new class version is higher than 1
3451 // AND the checksum is the same.
3452 if (v2file || version == cl->GetClassVersion() || version == 1 ) {
3454
3455 // We need to check if another thread did not get here first
3456 // and did the StreamerInfo creation already.
3457 auto infos = cl->GetStreamerInfos();
3458 auto ninfos = infos->GetSize();
3459 if (!(version < -1 || version >= ninfos)) {
3460 sinfo = (TStreamerInfo *) infos->At(version);
3461 }
3462 if (!sinfo) {
3463 const_cast<TClass *>(cl)->BuildRealData(pointer);
3464 sinfo = new TStreamerInfo(const_cast<TClass *>(cl));
3465 sinfo->SetClassVersion(version);
3466 const_cast<TClass *>(cl)->RegisterStreamerInfo(sinfo);
3467 if (gDebug > 0)
3468 Info("ReadClassBuffer", "Creating StreamerInfo for class: %s, version: %d",
3469 cl->GetName(), version);
3470 if (v2file) {
3471 sinfo->Build(); // Get the elements.
3472 sinfo->Clear("build"); // Undo compilation.
3473 sinfo->BuildEmulated(file); // Fix the types and redo compilation.
3474 } else {
3475 sinfo->Build();
3476 }
3477 }
3478 } else if (version==0) {
3479 // When the object was written the class was version zero, so
3480 // there is no StreamerInfo to be found.
3481 // Check that the buffer position corresponds to the byte count.
3482 CheckByteCount(R__s, R__c, cl);
3483 return 0;
3484 } else {
3485 Error( "ReadClassBuffer", "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
3486 version, cl->GetName(), Length() );
3487 CheckByteCount(R__s, R__c, cl);
3488 return 0;
3489 }
3490 }
3491 }
3492 }
3493
3494 //deserialize the object
3495 ApplySequence(*(sinfo->GetReadObjectWiseActions()), (char*)pointer );
3496 if (sinfo->TStreamerInfo::IsRecovered()) R__c=0; // 'TStreamerInfo::' avoids going via a virtual function.
3497
3498 // Check that the buffer position corresponds to the byte count.
3499 CheckByteCount(R__s, R__c, cl);
3500
3501 if (gDebug > 2) Info("ReadClassBuffer", "For class: %s has read %d bytes", cl->GetName(), R__c);
3502
3503 return 0;
3504}
3505
3506////////////////////////////////////////////////////////////////////////////////
3507/// Function called by the Streamer functions to serialize object at p
3508/// to buffer b. The optional argument info may be specified to give an
3509/// alternative StreamerInfo instead of using the default StreamerInfo
3510/// automatically built from the class definition.
3511/// For more information, see class TStreamerInfo.
3512
3514{
3515 //build the StreamerInfo if first time for the class
3516 TStreamerInfo *sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetCurrentStreamerInfo();
3517 if (sinfo == nullptr) {
3518 //Have to be sure between the check and the taking of the lock if the current streamer has changed
3520 sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetCurrentStreamerInfo();
3521 if (sinfo == nullptr)
3522 sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetStreamerInfo();
3523 if (sinfo == nullptr) {
3524 const_cast<TClass*>(cl)->BuildRealData(pointer);
3525 sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
3526 const_cast<TClass*>(cl)->SetCurrentStreamerInfo(sinfo);
3527 const_cast<TClass*>(cl)->RegisterStreamerInfo(sinfo);
3528 if (gDebug > 0) Info("WritedClassBuffer", "Creating StreamerInfo for class: %s, version: %d",cl->GetName(),cl->GetClassVersion());
3529 sinfo->Build();
3530 }
3531 } else if (!sinfo->IsCompiled()) {
3533 // Redo the test in case we have been victim of a data race on fIsCompiled.
3534 if (!sinfo->IsCompiled()) {
3535 const_cast<TClass*>(cl)->BuildRealData(pointer);
3536 sinfo->BuildOld();
3537 }
3538 }
3539
3540 //write the class version number and reserve space for the byte count
3541 UInt_t R__c = WriteVersion(cl, kTRUE);
3542
3543 //NOTE: In the future Philippe wants this to happen via a custom action
3544 TagStreamerInfo(sinfo);
3545 ApplySequence(*(sinfo->GetWriteObjectWiseActions()), (char*)pointer);
3546
3547 //write the byte count at the start of the buffer
3548 SetByteCount(R__c, kTRUE);
3549
3550 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));
3551 return 0;
3552}
3553
3554////////////////////////////////////////////////////////////////////////////////
3555/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3556/// The collection needs to be a split TClonesArray or a split vector of pointers.
3557
3559{
3560 if (gDebug) {
3561 //loop on all active members
3562 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3563 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3564 iter != end;
3565 ++iter) {
3566 (*iter).PrintDebug(*this,obj);
3567 (*iter)(*this,obj);
3568 }
3569
3570 } else {
3571 //loop on all active members
3572 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3573 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3574 iter != end;
3575 ++iter) {
3576 (*iter)(*this,obj);
3577 }
3578 }
3579
3580 return 0;
3581}
3582
3583////////////////////////////////////////////////////////////////////////////////
3584/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3585/// The collection needs to be a split TClonesArray or a split vector of pointers.
3586
3587Int_t TBufferFile::ApplySequenceVecPtr(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
3588{
3589 if (gDebug) {
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 if (!start_collection || start_collection == end_collection)
3596 (*iter).PrintDebug(*this, nullptr); // Warning: This limits us to TClonesArray and vector of pointers.
3597 else
3598 (*iter).PrintDebug(*this, *(char**)start_collection); // Warning: This limits us to TClonesArray and vector of pointers.
3599 (*iter)(*this, start_collection, end_collection);
3600 }
3601
3602 } else {
3603 //loop on all active members
3604 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3605 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3606 iter != end;
3607 ++iter) {
3608 (*iter)(*this,start_collection,end_collection);
3609 }
3610 }
3611
3612 return 0;
3613}
3614
3615////////////////////////////////////////////////////////////////////////////////
3616/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3617
3618Int_t TBufferFile::ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
3619{
3621 if (gDebug) {
3622
3623 // Get the address of the first item for the PrintDebug.
3624 // (Performance is not essential here since we are going to print to
3625 // the screen anyway).
3626 void *arr0 = start_collection ? loopconfig->GetFirstAddress(start_collection,end_collection) : 0;
3627 // loop on all active members
3628 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3629 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3630 iter != end;
3631 ++iter) {
3632 (*iter).PrintDebug(*this,arr0);
3633 (*iter)(*this,start_collection,end_collection,loopconfig);
3634 }
3635
3636 } else {
3637 //loop on all active members
3638 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3639 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3640 iter != end;
3641 ++iter) {
3642 (*iter)(*this,start_collection,end_collection,loopconfig);
3643 }
3644 }
3645
3646 return 0;
3647}
void * bswapcpy16(void *to, const void *from, size_t n)
Definition Bswapcpy.h:45
void * bswapcpy32(void *to, const void *from, size_t n)
Definition Bswapcpy.h:60
void frombuf(char *&buf, Bool_t *x)
Definition Bytes.h:278
void tobuf(char *&buf, Bool_t x)
Definition Bytes.h:55
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
const Int_t kMaxInt
Definition RtypesCore.h:112
long Longptr_t
Definition RtypesCore.h:82
short Version_t
Definition RtypesCore.h:65
unsigned char UChar_t
Definition RtypesCore.h:38
unsigned long ULongptr_t
Definition RtypesCore.h:83
char Char_t
Definition RtypesCore.h:37
unsigned int UInt_t
Definition RtypesCore.h:46
const Bool_t kFALSE
Definition RtypesCore.h:101
unsigned long ULong_t
Definition RtypesCore.h:55
long Long_t
Definition RtypesCore.h:54
bool Bool_t
Definition RtypesCore.h:63
short Short_t
Definition RtypesCore.h:39
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:80
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
const UInt_t kMaxMapCount
const Int_t kMapOffset
const UInt_t kNewClassTag
static void frombufOld(char *&buf, Long_t *x)
Handle old file formats.
const Version_t kMaxVersion
const UInt_t kClassMask
static bool Class_Has_StreamerInfo(const TClass *cl)
Thread-safe check on StreamerInfos of a TClass.
const Version_t kByteCountVMask
const UInt_t kByteCountMask
@ kIsAbstract
Definition TDictionary.h:71
#define R__ASSERT(e)
Definition TError.h:118
char name[80]
Definition TGX11.cxx:110
float xmin
float xmax
R__EXTERN TVirtualMutex * gInterpreterMutex
Int_t gDebug
Definition TROOT.cxx:592
char *(* ReAllocCharFun_t)(char *, size_t, size_t)
Definition TStorage.h:30
#define R__LOCKGUARD(mutex)
#define R__WRITE_LOCKGUARD(mutex)
#define R__READ_LOCKGUARD(mutex)
Bool_t HasRuleWithSourceClass(const TString &source) const
Return True if we have any rule whose source class is 'source'.
The concrete implementation of TBuffer for writing/reading to/from a ROOT file or socket.
Definition TBufferFile.h:47
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...
void WriteBuf(const void *buf, Int_t max) override
Write max bytes from buf into the I/O buffer.
TObject * ReadObject(const TClass *cl) override
Read object from I/O buffer.
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...
Int_t ReadStaticArrayFloat16(Float_t *f, TStreamerElement *ele=nullptr) override
Read array of floats (written as truncated float) from the I/O buffer.
void DecrementLevel(TVirtualStreamerInfo *) override
Decrement level.
Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr) override
Read class version from I/O buffer.
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/...
virtual ~TBufferFile()
Delete an I/O buffer object.
void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE) override
Set byte count at position cntpos in the buffer.
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...
void WriteObjectClass(const void *actualObjStart, const TClass *actualClass, Bool_t cacheReuse) override
Write object to I/O buffer.
void ReadTString(TString &s) override
Read TString from TBuffer.
void ReadCharStar(char *&s) override
Read char* from TBuffer.
void StreamObject(void *obj, const std::type_info &typeinfo, const TClass *onFileClass=nullptr) override
Stream an object given its C++ typeinfo information.
UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE) override
Write class version to I/O buffer.
Int_t ReadBuf(void *buf, Int_t max) override
Read max bytes from the I/O buffer into buf.
void WriteString(const char *s) override
Write string to I/O buffer.
char * ReadString(char *s, Int_t max) override
Read string from I/O buffer.
void WriteArray(const Bool_t *b, Int_t n) override
Write array of n bools into the I/O buffer.
void ReadFastArray(Bool_t *b, Int_t n) override
Read array of n bools from the I/O buffer.
void ReadFastArrayString(Char_t *c, Int_t n) override
Read array of n characters from the I/O buffer.
Int_t ReadArray(Bool_t *&b) override
Read array of bools from the I/O buffer.
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.
Int_t ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *object) override
Read one collection of objects from the buffer using the StreamerInfoLoopAction.
void * ReadObjectAny(const TClass *cast) override
Read object from I/O buffer.
void SkipObjectAny() override
Skip any kind of object from buffer.
Int_t ReadStaticArrayDouble32(Double_t *d, TStreamerElement *ele=nullptr) override
Read array of doubles (written as float) from the I/O buffer.
TClass * ReadClass(const TClass *cl=nullptr, UInt_t *objTag=nullptr) override
Read class definition from I/O buffer.
Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class) override
Deserialize information from a buffer into an object.
void SkipVersion(const TClass *cl=nullptr) override
Skip class version from I/O buffer.
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(...
@ kStreamedMemberWise
Definition TBufferFile.h:69
Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss, const char *classname)
Check byte count with current buffer position.
void WriteCharStar(char *s) override
Write char* into TBuffer.
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.
void WriteStdString(const std::string *s) override
Write std::string to TBuffer.
Int_t WriteClassBuffer(const TClass *cl, void *pointer) override
Function called by the Streamer functions to serialize object at p to buffer b.
void WriteClass(const TClass *cl) override
Write class description to I/O buffer.
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.
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.
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.
void CheckCount(UInt_t offset) override
Check if offset is not too large (< kMaxMapCount) when writing.
Int_t ReadArrayFloat16(Float_t *&f, TStreamerElement *ele=nullptr) override
Read array of floats (written as truncated float) from the I/O buffer.
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.
void ReadStdString(std::string *s) override
Read std::string from TBuffer.
void WriteFloat16(Float_t *f, TStreamerElement *ele=nullptr) override
Write a Float16_t to the buffer.
Int_t ReadStaticArray(Bool_t *b) override
Read array of bools from the I/O buffer.
void WriteTString(const TString &s) override
Write TString to TBuffer.
UInt_t CheckObject(UInt_t offset, const TClass *cl, Bool_t readClass=kFALSE)
Check for object in the read map.
InfoList_t fInfoStack
Stack of pointers to the TStreamerInfos.
Definition TBufferFile.h:53
void WriteDouble32(Double_t *d, TStreamerElement *ele=nullptr) override
Write a Double32_t to the buffer.
void ReadLong(Long_t &l) override
Read Long from TBuffer.
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.
void IncrementLevel(TVirtualStreamerInfo *info) override
Increment level.
Int_t ReadArrayDouble32(Double_t *&d, TStreamerElement *ele=nullptr) override
Read array of doubles (written as float) from the I/O buffer.
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.
void WriteFastArrayString(const Char_t *c, Int_t n) override
Write array of n characters into the I/O buffer.
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.
void WriteFastArray(const Bool_t *b, Int_t n) override
Write array of n bools into the I/O buffer.
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.
Version_t ReadVersionForMemberWise(const TClass *cl=nullptr) override
Read class version from I/O buffer.
TStreamerInfo * fInfo
Pointer to TStreamerInfo object writing/reading the buffer.
Definition TBufferFile.h:52
Int_t ReadClassEmulated(const TClass *cl, void *object, const TClass *onfile_class) override
Read emulated class.
Direct subclass of TBuffer, implements common methods for TBufferFile and TBufferText classes.
Definition TBufferIO.h:30
void InitMap() override
Create the fMap container and initialize them with the null object.
void ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t force) override
force writing the TStreamerInfo to the file
TExMap * fMap
Map containing object,offset pairs for reading/writing.
Definition TBufferIO.h:39
void MapObject(const TObject *obj, UInt_t offset=1) override
Add object to the fMap container.
TExMap * fClassMap
Map containing object,class pairs for reading.
Definition TBufferIO.h:40
Int_t fDisplacement
Value to be added to the map offsets.
Definition TBufferIO.h:37
static R__ALWAYS_INLINE ULong_t Void_Hash(const void *ptr)
Return hash value for provided object.
Definition TBufferIO.h:53
Int_t fMapCount
Number of objects or classes in map.
Definition TBufferIO.h:35
void TagStreamerInfo(TVirtualStreamerInfo *info) override
Mark the classindex of the current file as using this TStreamerInfo.
Int_t WriteObjectAny(const void *obj, const TClass *ptrClass, Bool_t cacheReuse=kTRUE) override
Write object to I/O buffer.
Int_t fBufSize
Definition TBuffer.h:50
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition TBuffer.cxx:262
char * fBufMax
Definition TBuffer.h:53
char * fBufCur
Definition TBuffer.h:52
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
Bool_t IsWriting() const
Definition TBuffer.h:87
Bool_t IsReading() const
Definition TBuffer.h:86
void SetBufferOffset(Int_t offset=0)
Definition TBuffer.h:93
char * fBuffer
Definition TBuffer.h:51
TObject * fParent
Definition TBuffer.h:54
Int_t fVersion
Definition TBuffer.h:49
Int_t Length() const
Definition TBuffer.h:100
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:80
UInt_t GetCheckSum(ECheckSum code=kCurrentCheckSum) const
Call GetCheckSum with validity check.
Definition TClass.cxx:6491
EState GetState() const
Definition TClass.h:485
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:4964
static TClass * Load(TBuffer &b)
Load class description from I/O buffer and return class object.
Definition TClass.cxx:5701
TVirtualStreamerInfo * GetCurrentStreamerInfo()
Definition TClass.h:436
void SetLastReadInfo(TVirtualStreamerInfo *info)
Definition TClass.h:442
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:6480
TVirtualStreamerInfo * GetLastReadInfo() const
Definition TClass.h:441
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5690
const ROOT::Detail::TSchemaRuleSet * GetSchemaRules() const
Return the set of the schema rules if any.
Definition TClass.cxx:1930
void Store(TBuffer &b) const
Store class description on I/O buffer.
Definition TClass.cxx:5846
const TObjArray * GetStreamerInfos() const
Definition TClass.h:489
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5898
Bool_t IsForeign() const
Return kTRUE is the class is Foreign (the class does not have a Streamer method).
Definition TClass.cxx:5933
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition TClass.cxx:2789
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0, Bool_t isTransient=kFALSE) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Definition TClass.cxx:4585
Long_t Property() const
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6072
Bool_t HasDefaultConstructor(Bool_t testio=kFALSE) const
Return true if we have access to a constructor usable for I/O.
Definition TClass.cxx:7379
void Streamer(void *obj, TBuffer &b, const TClass *onfile_class=0) const
Definition TClass.h:602
TVirtualStreamerInfo * GetConversionStreamerInfo(const char *onfile_classname, Int_t version) const
Return a Conversion StreamerInfo from the class 'classname' for version number 'version' to this clas...
Definition TClass.cxx:7072
@ kEmulated
Definition TClass.h:125
TVirtualStreamerInfo * FindStreamerInfo(TObjArray *arr, UInt_t checksum) const
Find the TVirtualStreamerInfo in the StreamerInfos corresponding to checksum.
Definition TClass.cxx:7052
Version_t GetClassVersion() const
Definition TClass.h:417
Bool_t InheritsFrom(const char *cl) const
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4860
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:2966
Int_t Capacity() const
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Int_t GetSize() const
Definition TExMap.h:71
void Remove(ULong64_t hash, Long64_t key)
Remove entry with specified key from the TExMap.
Definition TExMap.cxx:216
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
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition TExMap.cxx:173
Int_t Capacity() const
Definition TExMap.h:69
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
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
A doubly linked list.
Definition TList.h:38
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition TList.cxx:578
virtual void SetOnFileClass(const TClass *cl)
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
An array of TObjects.
Definition TObjArray.h:31
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:84
Int_t GetLast() const
Return index of last object in array.
TObject * At(Int_t idx) const
Definition TObjArray.h:164
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:429
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:949
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:963
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:937
Double_t GetXmax() const
Double_t GetFactor() const
Double_t GetXmin() const
TLoopConfiguration * fLoopConfig
If this is a bundle of memberwise streaming action, this configures the looping.
Base class of the Configurations for the member wise looping routines.
virtual void * GetFirstAddress(void *start, const void *end) const =0
Describes a persistent version of a class.
void SetClassVersion(Int_t vers)
void Clear(Option_t *)
If opt contains 'built', reset this StreamerInfo as if Build or BuildOld was never called on it (usef...
TStreamerInfoActions::TActionSequence * GetReadObjectWiseActions()
void Build(Bool_t isTransient=kFALSE)
Build the I/O data structure for the current class version.
TStreamerInfoActions::TActionSequence * GetWriteObjectWiseActions()
void BuildEmulated(TFile *file)
Create an Emulation TStreamerInfo object.
Int_t GetClassVersion() const
void BuildOld()
rebuild the TStreamerInfo structure
UInt_t GetCheckSum() const
Basic string class.
Definition TString.h:136
Ssiz_t Length() const
Definition TString.h:410
void UnLink() const
Definition TString.h:254
void SetSize(Ssiz_t s)
Definition TString.h:239
void Zero()
Definition TString.h:255
char * GetPointer()
Definition TString.h:247
void Clobber(Ssiz_t nc)
Clear string and make sure it has a capacity of nc.
Definition TString.cxx:1209
Abstract Interface class describing Streamer information for one class.
static Bool_t CanDelete()
static function returning true if ReadBuffer can delete object
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
R__EXTERN TVirtualRWMutex * gCoreMutex
Short_t Min(Short_t a, Short_t b)
Definition TMathBase.h:176
Definition file.py:1
auto * l
Definition textangle.C:4