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
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
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 ) {
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/// In Case A and E, the exponent is stored as is (8 bits), for a total of 21 bits (including 1 bit for sign)
559///
560/// The range specifier has the general format: [xmin,xmax] or [xmin,xmax,nbits]
561/// - [0,1];
562/// - [-10,100];
563/// - [-pi,pi], [-pi/2,pi/4],[-2pi,2*pi]
564/// - [-10,100,16]
565/// - [0,0,8]
566/// if nbits is not specified, or nbits <2 or nbits>16 it is set to 16. If
567/// (xmin==0 and xmax==0 and nbits <=14) the float word will have
568/// its mantissa truncated to nbits significative bits.
569///
570/// ## IMPORTANT NOTE
571/// ### NOTE 1
572/// Lets assume an original variable float x:
573/// When using the format [0,0,8] (ie range not specified) you get the best
574/// relative precision when storing and reading back the truncated x, say xt.
575/// The variance of (x-xt)/x will be better than when specifying a range
576/// for the same number of bits. However the precision relative to the
577/// range (x-xt)/(xmax-xmin) will be worst, and vice-versa.
578/// The format [0,0,8] is also interesting when the range of x is infinite
579/// or unknown.
580///
581/// ### NOTE 2
582/// It is important to understand the difference with the meaning of nbits
583/// - in case of [-1,1,nbits], nbits is the total number of bits used to make
584/// the conversion from a float to an integer
585/// - in case of [0,0,nbits], nbits is the number of bits used for the mantissa, to which is added 8 bits for the exponent.
586///
587/// See example of use of the Float16_t data type in tutorial float16.C
588/// \image html tbufferfile_double32.gif
589
591{
592
593 if (ele && ele->GetFactor() != 0) {
594 //A range is specified. We normalize the double to the range and
595 //convert it to an integer using a scaling factor that is a function of nbits.
596 //see TStreamerElement::GetRange.
597 Double_t x = f[0];
598 Double_t xmin = ele->GetXmin();
599 Double_t xmax = ele->GetXmax();
600 if (x < xmin) x = xmin;
601 if (x > xmax) x = xmax;
602 UInt_t aint = UInt_t(0.5+ele->GetFactor()*(x-xmin)); *this << aint;
603 } else {
604 Int_t nbits = 0;
605 //number of bits stored in fXmin (see TStreamerElement::GetRange)
606 if (ele) nbits = (Int_t)ele->GetXmin();
607 if (!nbits) nbits = 12;
608 //a range is not specified, but nbits is.
609 //In this case we truncate the mantissa to nbits and we stream
610 //the exponent as a UChar_t and the mantissa as a UShort_t.
611 union {
612 Float_t fFloatValue;
613 Int_t fIntValue;
614 };
615 fFloatValue = f[0];
616 UChar_t theExp = (UChar_t)(0x000000ff & ((fIntValue<<1)>>24));
617 UShort_t theMan = ((1<<(nbits+1))-1) & (fIntValue>>(23-nbits-1));
618 theMan++;
619 theMan = theMan>>1;
620 if (theMan&1<<nbits) theMan = (1<<nbits) - 1;
621 if (fFloatValue < 0) theMan |= 1<<(nbits+1);
622 *this << theExp;
623 *this << theMan;
624 }
625}
626
627////////////////////////////////////////////////////////////////////////////////
628/// Write a Double32_t to the buffer.
629///
630/// The following cases are supported for streaming a Double32_t type
631/// depending on the range declaration in the comment field of the data member:
632/// Case | Example |
633/// -----|---------|
634/// A | Double32_t fNormal; |
635/// B | Double32_t fTemperature; //[0,100]|
636/// C | Double32_t fCharge; //[-1,1,2]|
637/// D | Double32_t fVertex[3]; //[-30,30,10]|
638/// E | Double32_t fChi2; //[0,0,6]|
639/// F | Int_t fNsp;<br>Double32_t* fPointValue; //[fNsp][0,3]|
640///
641/// In case A fNormal is converted from a Double_t to a Float_t
642/// In case B fTemperature is converted to a 32 bit unsigned integer
643/// In case C fCharge is converted to a 2 bits unsigned integer
644/// In case D the array elements of fVertex are converted to an unsigned 10 bits integer
645/// In case E fChi2 is converted to a Float_t with mantissa truncated precision at 6 bits
646/// In case F the fNsp elements of array fPointvalue are converted to an unsigned 32 bit integer
647/// Note that the range specifier must follow the dimension specifier.
648/// Case B has more precision (9 to 10 significative digits than case A (6 to 7 digits).
649/// See TBufferFile::WriteFloat16 for more information.
650///
651/// see example of use of the Double32_t data type in tutorial double32.C
652/// \image html tbufferfile_double32.gif
653
655{
656
657 if (ele && ele->GetFactor() != 0) {
658 //A range is specified. We normalize the double to the range and
659 //convert it to an integer using a scaling factor that is a function of nbits.
660 //see TStreamerElement::GetRange.
661 Double_t x = d[0];
662 Double_t xmin = ele->GetXmin();
663 Double_t xmax = ele->GetXmax();
664 if (x < xmin) x = xmin;
665 if (x > xmax) x = xmax;
666 UInt_t aint = UInt_t(0.5+ele->GetFactor()*(x-xmin)); *this << aint;
667 } else {
668 Int_t nbits = 0;
669 //number of bits stored in fXmin (see TStreamerElement::GetRange)
670 if (ele) nbits = (Int_t)ele->GetXmin();
671 if (!nbits) {
672 //if no range and no bits specified, we convert from double to float
673 Float_t afloat = (Float_t)d[0];
674 *this << afloat;
675 } else {
676 //a range is not specified, but nbits is.
677 //In this case we truncate the mantissa to nbits and we stream
678 //the exponent as a UChar_t and the mantissa as a UShort_t.
679 union {
680 Float_t fFloatValue;
681 Int_t fIntValue;
682 };
683 fFloatValue = (Float_t)d[0];
684 UChar_t theExp = (UChar_t)(0x000000ff & ((fIntValue<<1)>>24));
685 UShort_t theMan = ((1<<(nbits+1))-1) & (fIntValue>>(23-nbits-1)) ;
686 theMan++;
687 theMan = theMan>>1;
688 if (theMan&1<<nbits) theMan = (1<<nbits)-1 ;
689 if (fFloatValue < 0) theMan |= 1<<(nbits+1);
690 *this << theExp;
691 *this << theMan;
692 }
693 }
694}
695
696////////////////////////////////////////////////////////////////////////////////
697/// Read array of bools from the I/O buffer. Returns the number of
698/// bools read. If argument is a 0 pointer then space will be
699/// allocated for the array.
700
702{
704
705 Int_t n;
706 *this >> n;
707
708 if (n <= 0 || n > fBufSize) return 0;
709
710 if (!b) b = new Bool_t[n];
711
712 if (sizeof(Bool_t) > 1) {
713 for (int i = 0; i < n; i++)
714 frombuf(fBufCur, &b[i]);
715 } else {
716 Int_t l = sizeof(Bool_t)*n;
717 memcpy(b, fBufCur, l);
718 fBufCur += l;
719 }
720
721 return n;
722}
723
724////////////////////////////////////////////////////////////////////////////////
725/// Read array of characters from the I/O buffer. Returns the number of
726/// characters read. If argument is a 0 pointer then space will be
727/// allocated for the array.
728
730{
732
733 Int_t n;
734 *this >> n;
735 Int_t l = sizeof(Char_t)*n;
736
737 if (l <= 0 || l > fBufSize) return 0;
738
739 if (!c) c = new Char_t[n];
740
741 memcpy(c, fBufCur, l);
742 fBufCur += l;
743
744 return n;
745}
746
747////////////////////////////////////////////////////////////////////////////////
748/// Read array of shorts from the I/O buffer. Returns the number of shorts
749/// read. If argument is a 0 pointer then space will be allocated for the
750/// array.
751
753{
755
756 Int_t n;
757 *this >> n;
758 Int_t l = sizeof(Short_t)*n;
759
760 if (l <= 0 || l > fBufSize) return 0;
761
762 if (!h) h = new Short_t[n];
763
764#ifdef R__BYTESWAP
765# ifdef USE_BSWAPCPY
767 fBufCur += l;
768# else
769 for (int i = 0; i < n; i++)
770 frombuf(fBufCur, &h[i]);
771# endif
772#else
773 memcpy(h, fBufCur, l);
774 fBufCur += l;
775#endif
776
777 return n;
778}
779
780////////////////////////////////////////////////////////////////////////////////
781/// Read array of ints from the I/O buffer. Returns the number of ints
782/// read. If argument is a 0 pointer then space will be allocated for the
783/// array.
784
786{
788
789 Int_t n;
790 *this >> n;
791 Int_t l = sizeof(Int_t)*n;
792
793 if (l <= 0 || l > fBufSize) return 0;
794
795 if (!ii) ii = new Int_t[n];
796
797#ifdef R__BYTESWAP
798# ifdef USE_BSWAPCPY
799 bswapcpy32(ii, fBufCur, n);
800 fBufCur += l;
801# else
802 for (int i = 0; i < n; i++)
803 frombuf(fBufCur, &ii[i]);
804# endif
805#else
806 memcpy(ii, fBufCur, l);
807 fBufCur += l;
808#endif
809
810 return n;
811}
812
813////////////////////////////////////////////////////////////////////////////////
814/// Read array of longs from the I/O buffer. Returns the number of longs
815/// read. If argument is a 0 pointer then space will be allocated for the
816/// array.
817
819{
821
822 Int_t n;
823 *this >> n;
824 Int_t l = sizeof(Long_t)*n;
825
826 if (l <= 0 || l > fBufSize) return 0;
827
828 if (!ll) ll = new Long_t[n];
829
830 TFile *file = (TFile*)fParent;
831 if (file && file->GetVersion() < 30006) {
832 for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
833 } else {
834 for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
835 }
836 return n;
837}
838
839////////////////////////////////////////////////////////////////////////////////
840/// Read array of long longs from the I/O buffer. Returns the number of
841/// long longs read. If argument is a 0 pointer then space will be
842/// allocated for the array.
843
845{
847
848 Int_t n;
849 *this >> n;
850 Int_t l = sizeof(Long64_t)*n;
851
852 if (l <= 0 || l > fBufSize) return 0;
853
854 if (!ll) ll = new Long64_t[n];
855
856#ifdef R__BYTESWAP
857 for (int i = 0; i < n; i++)
858 frombuf(fBufCur, &ll[i]);
859#else
860 memcpy(ll, fBufCur, l);
861 fBufCur += l;
862#endif
863
864 return n;
865}
866
867////////////////////////////////////////////////////////////////////////////////
868/// Read array of floats from the I/O buffer. Returns the number of floats
869/// read. If argument is a 0 pointer then space will be allocated for the
870/// array.
871
873{
875
876 Int_t n;
877 *this >> n;
878 Int_t l = sizeof(Float_t)*n;
879
880 if (l <= 0 || l > fBufSize) return 0;
881
882 if (!f) f = new Float_t[n];
883
884#ifdef R__BYTESWAP
885# ifdef USE_BSWAPCPY
887 fBufCur += l;
888# else
889 for (int i = 0; i < n; i++)
890 frombuf(fBufCur, &f[i]);
891# endif
892#else
893 memcpy(f, fBufCur, l);
894 fBufCur += l;
895#endif
896
897 return n;
898}
899
900////////////////////////////////////////////////////////////////////////////////
901/// Read array of doubles from the I/O buffer. Returns the number of doubles
902/// read. If argument is a 0 pointer then space will be allocated for the
903/// array.
904
906{
908
909 Int_t n;
910 *this >> n;
911 Int_t l = sizeof(Double_t)*n;
912
913 if (l <= 0 || l > fBufSize) return 0;
914
915 if (!d) d = new Double_t[n];
916
917#ifdef R__BYTESWAP
918 for (int i = 0; i < n; i++)
919 frombuf(fBufCur, &d[i]);
920#else
921 memcpy(d, fBufCur, l);
922 fBufCur += l;
923#endif
924
925 return n;
926}
927
928////////////////////////////////////////////////////////////////////////////////
929/// Read array of floats (written as truncated float) from the I/O buffer.
930/// Returns the number of floats read.
931/// If argument is a 0 pointer then space will be allocated for the array.
932/// see comments about Float16_t encoding at TBufferFile::WriteFloat16
933
935{
937
938 Int_t n;
939 *this >> n;
940
941 if (n <= 0 || 3*n > fBufSize) return 0;
942
943 if (!f) f = new Float_t[n];
944
946
947 return n;
948}
949
950////////////////////////////////////////////////////////////////////////////////
951/// Read array of doubles (written as float) from the I/O buffer.
952/// Returns the number of doubles read.
953/// If argument is a 0 pointer then space will be allocated for the array.
954/// see comments about Double32_t encoding at TBufferFile::WriteDouble32
955
957{
959
960 Int_t n;
961 *this >> n;
962
963 if (n <= 0 || 3*n > fBufSize) return 0;
964
965 if (!d) d = new Double_t[n];
966
968
969 return n;
970}
971
972////////////////////////////////////////////////////////////////////////////////
973/// Read array of bools from the I/O buffer. Returns the number of bools
974/// read.
975
977{
979
980 Int_t n;
981 *this >> n;
982
983 if (n <= 0 || n > fBufSize) return 0;
984
985 if (!b) return 0;
986
987 if (sizeof(Bool_t) > 1) {
988 for (int i = 0; i < n; i++)
989 frombuf(fBufCur, &b[i]);
990 } else {
991 Int_t l = sizeof(Bool_t)*n;
992 memcpy(b, fBufCur, l);
993 fBufCur += l;
994 }
995
996 return n;
997}
998
999////////////////////////////////////////////////////////////////////////////////
1000/// Read array of characters from the I/O buffer. Returns the number of
1001/// characters read.
1002
1004{
1006
1007 Int_t n;
1008 *this >> n;
1009 Int_t l = sizeof(Char_t)*n;
1010
1011 if (l <= 0 || l > fBufSize) return 0;
1012
1013 if (!c) return 0;
1014
1015 memcpy(c, fBufCur, l);
1016 fBufCur += l;
1017
1018 return n;
1019}
1020
1021////////////////////////////////////////////////////////////////////////////////
1022/// Read array of shorts from the I/O buffer. Returns the number of shorts
1023/// read.
1024
1026{
1028
1029 Int_t n;
1030 *this >> n;
1031 Int_t l = sizeof(Short_t)*n;
1032
1033 if (l <= 0 || l > fBufSize) return 0;
1034
1035 if (!h) return 0;
1036
1037#ifdef R__BYTESWAP
1038# ifdef USE_BSWAPCPY
1039 bswapcpy16(h, fBufCur, n);
1040 fBufCur += l;
1041# else
1042 for (int i = 0; i < n; i++)
1043 frombuf(fBufCur, &h[i]);
1044# endif
1045#else
1046 memcpy(h, fBufCur, l);
1047 fBufCur += l;
1048#endif
1049
1050 return n;
1051}
1052
1053////////////////////////////////////////////////////////////////////////////////
1054/// Read array of ints from the I/O buffer. Returns the number of ints
1055/// read.
1056
1058{
1060
1061 Int_t n;
1062 *this >> n;
1063 Int_t l = sizeof(Int_t)*n;
1064
1065 if (l <= 0 || l > fBufSize) return 0;
1066
1067 if (!ii) return 0;
1068
1069#ifdef R__BYTESWAP
1070# ifdef USE_BSWAPCPY
1071 bswapcpy32(ii, fBufCur, n);
1072 fBufCur += sizeof(Int_t)*n;
1073# else
1074 for (int i = 0; i < n; i++)
1075 frombuf(fBufCur, &ii[i]);
1076# endif
1077#else
1078 memcpy(ii, fBufCur, l);
1079 fBufCur += l;
1080#endif
1081
1082 return n;
1083}
1084
1085////////////////////////////////////////////////////////////////////////////////
1086/// Read array of longs from the I/O buffer. Returns the number of longs
1087/// read.
1088
1090{
1092
1093 Int_t n;
1094 *this >> n;
1095 Int_t l = sizeof(Long_t)*n;
1096
1097 if (l <= 0 || l > fBufSize) return 0;
1098
1099 if (!ll) return 0;
1100
1101 TFile *file = (TFile*)fParent;
1102 if (file && file->GetVersion() < 30006) {
1103 for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
1104 } else {
1105 for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
1106 }
1107 return n;
1108}
1109
1110////////////////////////////////////////////////////////////////////////////////
1111/// Read array of long longs from the I/O buffer. Returns the number of
1112/// long longs read.
1113
1115{
1117
1118 Int_t n;
1119 *this >> n;
1120 Int_t l = sizeof(Long64_t)*n;
1121
1122 if (l <= 0 || l > fBufSize) return 0;
1123
1124 if (!ll) return 0;
1125
1126#ifdef R__BYTESWAP
1127 for (int i = 0; i < n; i++)
1128 frombuf(fBufCur, &ll[i]);
1129#else
1130 memcpy(ll, fBufCur, l);
1131 fBufCur += l;
1132#endif
1133
1134 return n;
1135}
1136
1137////////////////////////////////////////////////////////////////////////////////
1138/// Read array of floats from the I/O buffer. Returns the number of floats
1139/// read.
1140
1142{
1144
1145 Int_t n;
1146 *this >> n;
1147 Int_t l = sizeof(Float_t)*n;
1148
1149 if (n <= 0 || l > fBufSize) return 0;
1150
1151 if (!f) return 0;
1152
1153#ifdef R__BYTESWAP
1154# ifdef USE_BSWAPCPY
1155 bswapcpy32(f, fBufCur, n);
1156 fBufCur += sizeof(Float_t)*n;
1157# else
1158 for (int i = 0; i < n; i++)
1159 frombuf(fBufCur, &f[i]);
1160# endif
1161#else
1162 memcpy(f, fBufCur, l);
1163 fBufCur += l;
1164#endif
1165
1166 return n;
1167}
1168
1169////////////////////////////////////////////////////////////////////////////////
1170/// Read array of doubles from the I/O buffer. Returns the number of doubles
1171/// read.
1172
1174{
1176
1177 Int_t n;
1178 *this >> n;
1179 Int_t l = sizeof(Double_t)*n;
1180
1181 if (n <= 0 || l > fBufSize) return 0;
1182
1183 if (!d) return 0;
1184
1185#ifdef R__BYTESWAP
1186 for (int i = 0; i < n; i++)
1187 frombuf(fBufCur, &d[i]);
1188#else
1189 memcpy(d, fBufCur, l);
1190 fBufCur += l;
1191#endif
1192
1193 return n;
1194}
1195
1196////////////////////////////////////////////////////////////////////////////////
1197/// Read array of floats (written as truncated float) from the I/O buffer.
1198/// Returns the number of floats read.
1199/// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1200
1202{
1204
1205 Int_t n;
1206 *this >> n;
1207
1208 if (n <= 0 || 3*n > fBufSize) return 0;
1209
1210 if (!f) return 0;
1211
1213
1214 return n;
1215}
1216
1217////////////////////////////////////////////////////////////////////////////////
1218/// Read array of doubles (written as float) from the I/O buffer.
1219/// Returns the number of doubles read.
1220/// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1221
1223{
1225
1226 Int_t n;
1227 *this >> n;
1228
1229 if (n <= 0 || 3*n > fBufSize) return 0;
1230
1231 if (!d) return 0;
1232
1234
1235 return n;
1236}
1237
1238////////////////////////////////////////////////////////////////////////////////
1239/// Read array of n bools from the I/O buffer.
1240
1242{
1243 if (n <= 0 || n > fBufSize) return;
1244
1245 if (sizeof(Bool_t) > 1) {
1246 for (int i = 0; i < n; i++)
1247 frombuf(fBufCur, &b[i]);
1248 } else {
1249 Int_t l = sizeof(Bool_t)*n;
1250 memcpy(b, fBufCur, l);
1251 fBufCur += l;
1252 }
1253}
1254
1255////////////////////////////////////////////////////////////////////////////////
1256/// Read array of n characters from the I/O buffer.
1257
1259{
1260 if (n <= 0 || n > fBufSize) return;
1261
1262 Int_t l = sizeof(Char_t)*n;
1263 memcpy(c, fBufCur, l);
1264 fBufCur += l;
1265}
1266
1267////////////////////////////////////////////////////////////////////////////////
1268/// Read array of n characters from the I/O buffer.
1269
1271{
1272 Int_t len;
1273 UChar_t lenchar;
1274 *this >> lenchar;
1275 if (lenchar < 255) {
1276 len = lenchar;
1277 } else {
1278 *this >> len;
1279 }
1280 if (len) {
1281 if (len <= 0 || len > fBufSize) return;
1282 Int_t blen = len;
1283 if (len >= n) len = n-1;
1284
1285 Int_t l = sizeof(Char_t)*len;
1286 memcpy(c, fBufCur, l);
1287 fBufCur += blen;
1288
1289 c[len] = 0;
1290 } else {
1291 c[0] = 0;
1292 }
1293}
1294
1295////////////////////////////////////////////////////////////////////////////////
1296/// Read array of n shorts from the I/O buffer.
1297
1299{
1300 Int_t l = sizeof(Short_t)*n;
1301 if (n <= 0 || l > fBufSize) return;
1302
1303#ifdef R__BYTESWAP
1304# ifdef USE_BSWAPCPY
1305 bswapcpy16(h, fBufCur, n);
1306 fBufCur += sizeof(Short_t)*n;
1307# else
1308 for (int i = 0; i < n; i++)
1309 frombuf(fBufCur, &h[i]);
1310# endif
1311#else
1312 memcpy(h, fBufCur, l);
1313 fBufCur += l;
1314#endif
1315}
1316
1317////////////////////////////////////////////////////////////////////////////////
1318/// Read array of n ints from the I/O buffer.
1319
1321{
1322 Int_t l = sizeof(Int_t)*n;
1323 if (l <= 0 || l > fBufSize) return;
1324
1325#ifdef R__BYTESWAP
1326# ifdef USE_BSWAPCPY
1327 bswapcpy32(ii, fBufCur, n);
1328 fBufCur += sizeof(Int_t)*n;
1329# else
1330 for (int i = 0; i < n; i++)
1331 frombuf(fBufCur, &ii[i]);
1332# endif
1333#else
1334 memcpy(ii, fBufCur, l);
1335 fBufCur += l;
1336#endif
1337}
1338
1339////////////////////////////////////////////////////////////////////////////////
1340/// Read array of n longs from the I/O buffer.
1341
1343{
1344 Int_t l = sizeof(Long_t)*n;
1345 if (l <= 0 || l > fBufSize) return;
1346
1347 TFile *file = (TFile*)fParent;
1348 if (file && file->GetVersion() < 30006) {
1349 for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
1350 } else {
1351 for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
1352 }
1353}
1354
1355////////////////////////////////////////////////////////////////////////////////
1356/// Read array of n long longs from the I/O buffer.
1357
1359{
1360 Int_t l = sizeof(Long64_t)*n;
1361 if (l <= 0 || l > fBufSize) return;
1362
1363#ifdef R__BYTESWAP
1364 for (int i = 0; i < n; i++)
1365 frombuf(fBufCur, &ll[i]);
1366#else
1367 memcpy(ll, fBufCur, l);
1368 fBufCur += l;
1369#endif
1370}
1371
1372////////////////////////////////////////////////////////////////////////////////
1373/// Read array of n floats from the I/O buffer.
1374
1376{
1377 Int_t l = sizeof(Float_t)*n;
1378 if (l <= 0 || l > fBufSize) return;
1379
1380#ifdef R__BYTESWAP
1381# ifdef USE_BSWAPCPY
1382 bswapcpy32(f, fBufCur, n);
1383 fBufCur += sizeof(Float_t)*n;
1384# else
1385 for (int i = 0; i < n; i++)
1386 frombuf(fBufCur, &f[i]);
1387# endif
1388#else
1389 memcpy(f, fBufCur, l);
1390 fBufCur += l;
1391#endif
1392}
1393
1394////////////////////////////////////////////////////////////////////////////////
1395/// Read array of n doubles from the I/O buffer.
1396
1398{
1399 Int_t l = sizeof(Double_t)*n;
1400 if (l <= 0 || l > fBufSize) return;
1401
1402#ifdef R__BYTESWAP
1403 for (int i = 0; i < n; i++)
1404 frombuf(fBufCur, &d[i]);
1405#else
1406 memcpy(d, fBufCur, l);
1407 fBufCur += l;
1408#endif
1409}
1410
1411////////////////////////////////////////////////////////////////////////////////
1412/// Read array of n floats (written as truncated float) from the I/O buffer.
1413/// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1414
1416{
1417 if (n <= 0 || 3*n > fBufSize) return;
1418
1419 if (ele && ele->GetFactor() != 0) {
1420 //a range was specified. We read an integer and convert it back to a float
1421 Double_t xmin = ele->GetXmin();
1422 Double_t factor = ele->GetFactor();
1423 for (int j=0;j < n; j++) {
1424 UInt_t aint; *this >> aint; f[j] = (Float_t)(aint/factor + xmin);
1425 }
1426 } else {
1427 Int_t i;
1428 Int_t nbits = 0;
1429 if (ele) nbits = (Int_t)ele->GetXmin();
1430 if (!nbits) nbits = 12;
1431 //we read the exponent and the truncated mantissa of the float
1432 //and rebuild the new float.
1433 union {
1434 Float_t fFloatValue;
1435 Int_t fIntValue;
1436 };
1437 UChar_t theExp;
1438 UShort_t theMan;
1439 for (i = 0; i < n; i++) {
1440 *this >> theExp;
1441 *this >> theMan;
1442 fIntValue = theExp;
1443 fIntValue <<= 23;
1444 fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
1445 if(1<<(nbits+1) & theMan) fFloatValue = -fFloatValue;
1446 f[i] = fFloatValue;
1447 }
1448 }
1449}
1450
1451////////////////////////////////////////////////////////////////////////////////
1452/// Read array of n floats (written as truncated float) from the I/O buffer.
1453/// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1454
1456{
1457 if (n <= 0 || 3*n > fBufSize) return;
1458
1459 //a range was specified. We read an integer and convert it back to a float
1460 for (int j=0;j < n; j++) {
1461 UInt_t aint; *this >> aint; ptr[j] = (Float_t)(aint/factor + minvalue);
1462 }
1463}
1464
1465////////////////////////////////////////////////////////////////////////////////
1466/// Read array of n floats (written as truncated float) from the I/O buffer.
1467/// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1468
1470{
1471 if (n <= 0 || 3*n > fBufSize) return;
1472
1473 if (!nbits) nbits = 12;
1474 //we read the exponent and the truncated mantissa of the float
1475 //and rebuild the new float.
1476 union {
1477 Float_t fFloatValue;
1478 Int_t fIntValue;
1479 };
1480 UChar_t theExp;
1481 UShort_t theMan;
1482 for (Int_t i = 0; i < n; i++) {
1483 *this >> theExp;
1484 *this >> theMan;
1485 fIntValue = theExp;
1486 fIntValue <<= 23;
1487 fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
1488 if(1<<(nbits+1) & theMan) fFloatValue = -fFloatValue;
1489 ptr[i] = fFloatValue;
1490 }
1491}
1492
1493////////////////////////////////////////////////////////////////////////////////
1494/// Read array of n doubles (written as float) from the I/O buffer.
1495/// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1496
1498{
1499 if (n <= 0 || 3*n > fBufSize) return;
1500
1501 if (ele && ele->GetFactor() != 0) {
1502 //a range was specified. We read an integer and convert it back to a double.
1503 Double_t xmin = ele->GetXmin();
1504 Double_t factor = ele->GetFactor();
1505 for (int j=0;j < n; j++) {
1506 UInt_t aint; *this >> aint; d[j] = (Double_t)(aint/factor + xmin);
1507 }
1508 } else {
1509 Int_t i;
1510 Int_t nbits = 0;
1511 if (ele) nbits = (Int_t)ele->GetXmin();
1512 if (!nbits) {
1513 //we read a float and convert it to double
1514 Float_t afloat;
1515 for (i = 0; i < n; i++) {
1516 *this >> afloat;
1517 d[i] = (Double_t)afloat;
1518 }
1519 } else {
1520 //we read the exponent and the truncated mantissa of the float
1521 //and rebuild the double.
1522 union {
1523 Float_t fFloatValue;
1524 Int_t fIntValue;
1525 };
1526 UChar_t theExp;
1527 UShort_t theMan;
1528 for (i = 0; i < n; i++) {
1529 *this >> theExp;
1530 *this >> theMan;
1531 fIntValue = theExp;
1532 fIntValue <<= 23;
1533 fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
1534 if (1<<(nbits+1) & theMan) fFloatValue = -fFloatValue;
1535 d[i] = (Double_t)fFloatValue;
1536 }
1537 }
1538 }
1539}
1540
1541////////////////////////////////////////////////////////////////////////////////
1542/// Read array of n doubles (written as float) from the I/O buffer.
1543/// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1544
1546{
1547 if (n <= 0 || 3*n > fBufSize) return;
1548
1549 //a range was specified. We read an integer and convert it back to a double.
1550 for (int j=0;j < n; j++) {
1551 UInt_t aint; *this >> aint; d[j] = (Double_t)(aint/factor + minvalue);
1552 }
1553}
1554
1555////////////////////////////////////////////////////////////////////////////////
1556/// Read array of n doubles (written as float) from the I/O buffer.
1557/// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1558
1560{
1561 if (n <= 0 || 3*n > fBufSize) return;
1562
1563 if (!nbits) {
1564 //we read a float and convert it to double
1565 Float_t afloat;
1566 for (Int_t i = 0; i < n; i++) {
1567 *this >> afloat;
1568 d[i] = (Double_t)afloat;
1569 }
1570 } else {
1571 //we read the exponent and the truncated mantissa of the float
1572 //and rebuild the double.
1573 union {
1574 Float_t fFloatValue;
1575 Int_t fIntValue;
1576 };
1577 UChar_t theExp;
1578 UShort_t theMan;
1579 for (Int_t i = 0; i < n; i++) {
1580 *this >> theExp;
1581 *this >> theMan;
1582 fIntValue = theExp;
1583 fIntValue <<= 23;
1584 fIntValue |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
1585 if (1<<(nbits+1) & theMan) fFloatValue = -fFloatValue;
1586 d[i] = (Double_t)fFloatValue;
1587 }
1588 }
1589}
1590
1591////////////////////////////////////////////////////////////////////////////////
1592/// Read an array of 'n' objects from the I/O buffer.
1593/// Stores the objects read starting at the address 'start'.
1594/// The objects in the array are assume to be of class 'cl'.
1595
1596void TBufferFile::ReadFastArray(void *start, const TClass *cl, Int_t n,
1597 TMemberStreamer *streamer, const TClass* onFileClass )
1598{
1599 if (streamer) {
1600 streamer->SetOnFileClass(onFileClass);
1601 (*streamer)(*this,start,0);
1602 return;
1603 }
1604
1605 int objectSize = cl->Size();
1606 char *obj = (char*)start;
1607 char *end = obj + n*objectSize;
1608
1609 for(; obj<end; obj+=objectSize) ((TClass*)cl)->Streamer(obj,*this, onFileClass);
1610}
1611
1612////////////////////////////////////////////////////////////////////////////////
1613/// Read an array of 'n' objects from the I/O buffer.
1614///
1615/// The objects read are stored starting at the address '*start'
1616/// The objects in the array are assumed to be of class 'cl' or a derived class.
1617/// 'mode' indicates whether the data member is marked with '->'
1618
1619void TBufferFile::ReadFastArray(void **start, const TClass *cl, Int_t n,
1620 Bool_t isPreAlloc, TMemberStreamer *streamer, const TClass* onFileClass)
1621{
1622 // if isPreAlloc is true (data member has a ->) we can assume that the pointer (*start)
1623 // is never 0.
1624
1625 if (streamer) {
1626 if (isPreAlloc) {
1627 for (Int_t j=0;j<n;j++) {
1628 if (!start[j]) start[j] = cl->New();
1629 }
1630 }
1631 streamer->SetOnFileClass(onFileClass);
1632 (*streamer)(*this,(void*)start,0);
1633 return;
1634 }
1635
1636 if (!isPreAlloc) {
1637
1638 for (Int_t j=0; j<n; j++){
1639 //delete the object or collection
1640 void *old = start[j];
1641 start[j] = ReadObjectAny(cl);
1642 if (old && old!=start[j] &&
1644 // There are some cases where the user may set up a pointer in the (default)
1645 // constructor but not mark this pointer as transient. Sometime the value
1646 // of this pointer is the address of one of the object with just created
1647 // and the following delete would result in the deletion (possibly of the
1648 // top level object we are goint to return!).
1649 // Eventhough this is a user error, we could prevent the crash by simply
1650 // adding:
1651 // && !CheckObject(start[j],cl)
1652 // However this can increase the read time significantly (10% in the case
1653 // of one TLine pointer in the test/Track and run ./Event 200 0 0 20 30000
1654 //
1655 // If ReadObjectAny returned the same value as we previous had, this means
1656 // that when writing this object (start[j] had already been written and
1657 // is indeed pointing to the same object as the object the user set up
1658 // in the default constructor).
1659 ) {
1660 ((TClass*)cl)->Destructor(old,kFALSE); // call delete and desctructor
1661 }
1662 }
1663
1664 } else {
1665 //case //-> in comment
1666
1667 for (Int_t j=0; j<n; j++){
1668 if (!start[j]) start[j] = ((TClass*)cl)->New();
1669 ((TClass*)cl)->Streamer(start[j],*this,onFileClass);
1670 }
1671
1672 }
1673}
1674
1675////////////////////////////////////////////////////////////////////////////////
1676/// Write array of n bools into the I/O buffer.
1677
1679{
1681
1682 *this << n;
1683
1684 if (n <= 0) return;
1685
1686 R__ASSERT(b);
1687
1688 Int_t l = sizeof(UChar_t)*n;
1690
1691 if (sizeof(Bool_t) > 1) {
1692 for (int i = 0; i < n; i++)
1693 tobuf(fBufCur, b[i]);
1694 } else {
1695 memcpy(fBufCur, b, l);
1696 fBufCur += l;
1697 }
1698}
1699
1700////////////////////////////////////////////////////////////////////////////////
1701/// Write array of n characters into the I/O buffer.
1702
1704{
1706
1707 *this << n;
1708
1709 if (n <= 0) return;
1710
1711 R__ASSERT(c);
1712
1713 Int_t l = sizeof(Char_t)*n;
1715
1716 memcpy(fBufCur, c, l);
1717 fBufCur += l;
1718}
1719
1720////////////////////////////////////////////////////////////////////////////////
1721/// Write array of n shorts into the I/O buffer.
1722
1724{
1726
1727 *this << n;
1728
1729 if (n <= 0) return;
1730
1731 R__ASSERT(h);
1732
1733 Int_t l = sizeof(Short_t)*n;
1735
1736#ifdef R__BYTESWAP
1737# ifdef USE_BSWAPCPY
1738 bswapcpy16(fBufCur, h, n);
1739 fBufCur += l;
1740# else
1741 for (int i = 0; i < n; i++)
1742 tobuf(fBufCur, h[i]);
1743# endif
1744#else
1745 memcpy(fBufCur, h, l);
1746 fBufCur += l;
1747#endif
1748}
1749
1750////////////////////////////////////////////////////////////////////////////////
1751/// Write array of n ints into the I/O buffer.
1752
1754{
1756
1757 *this << n;
1758
1759 if (n <= 0) return;
1760
1761 R__ASSERT(ii);
1762
1763 Int_t l = sizeof(Int_t)*n;
1765
1766#ifdef R__BYTESWAP
1767# ifdef USE_BSWAPCPY
1768 bswapcpy32(fBufCur, ii, n);
1769 fBufCur += l;
1770# else
1771 for (int i = 0; i < n; i++)
1772 tobuf(fBufCur, ii[i]);
1773# endif
1774#else
1775 memcpy(fBufCur, ii, l);
1776 fBufCur += l;
1777#endif
1778}
1779
1780////////////////////////////////////////////////////////////////////////////////
1781/// Write array of n longs into the I/O buffer.
1782
1784{
1786
1787 *this << n;
1788
1789 if (n <= 0) return;
1790
1791 R__ASSERT(ll);
1792
1793 Int_t l = 8*n;
1795 for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
1796}
1797
1798////////////////////////////////////////////////////////////////////////////////
1799/// Write array of n unsigned longs into the I/O buffer.
1800/// This is an explicit case for unsigned longs since signed longs
1801/// have a special tobuf().
1802
1804{
1806
1807 *this << n;
1808
1809 if (n <= 0) return;
1810
1811 R__ASSERT(ll);
1812
1813 Int_t l = 8*n;
1815 for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
1816}
1817
1818////////////////////////////////////////////////////////////////////////////////
1819/// Write array of n long longs into the I/O buffer.
1820
1822{
1824
1825 *this << n;
1826
1827 if (n <= 0) return;
1828
1829 R__ASSERT(ll);
1830
1831 Int_t l = sizeof(Long64_t)*n;
1833
1834#ifdef R__BYTESWAP
1835 for (int i = 0; i < n; i++)
1836 tobuf(fBufCur, ll[i]);
1837#else
1838 memcpy(fBufCur, ll, l);
1839 fBufCur += l;
1840#endif
1841}
1842
1843////////////////////////////////////////////////////////////////////////////////
1844/// Write array of n floats into the I/O buffer.
1845
1847{
1849
1850 *this << n;
1851
1852 if (n <= 0) return;
1853
1854 R__ASSERT(f);
1855
1856 Int_t l = sizeof(Float_t)*n;
1858
1859#ifdef R__BYTESWAP
1860# ifdef USE_BSWAPCPY
1861 bswapcpy32(fBufCur, f, n);
1862 fBufCur += l;
1863# else
1864 for (int i = 0; i < n; i++)
1865 tobuf(fBufCur, f[i]);
1866# endif
1867#else
1868 memcpy(fBufCur, f, l);
1869 fBufCur += l;
1870#endif
1871}
1872
1873////////////////////////////////////////////////////////////////////////////////
1874/// Write array of n doubles into the I/O buffer.
1875
1877{
1879
1880 *this << n;
1881
1882 if (n <= 0) return;
1883
1884 R__ASSERT(d);
1885
1886 Int_t l = sizeof(Double_t)*n;
1888
1889#ifdef R__BYTESWAP
1890 for (int i = 0; i < n; i++)
1891 tobuf(fBufCur, d[i]);
1892#else
1893 memcpy(fBufCur, d, l);
1894 fBufCur += l;
1895#endif
1896}
1897
1898////////////////////////////////////////////////////////////////////////////////
1899/// Write array of n floats (as truncated float) into the I/O buffer.
1900/// see comments about Float16_t encoding at TBufferFile::WriteFloat16
1901
1903{
1905
1906 *this << n;
1907
1908 if (n <= 0) return;
1909
1910 R__ASSERT(f);
1911
1912 Int_t l = sizeof(Float_t)*n;
1914
1916}
1917
1918////////////////////////////////////////////////////////////////////////////////
1919/// Write array of n doubles (as float) into the I/O buffer.
1920/// see comments about Double32_t encoding at TBufferFile::WriteDouble32
1921
1923{
1925
1926 *this << n;
1927
1928 if (n <= 0) return;
1929
1930 R__ASSERT(d);
1931
1932 Int_t l = sizeof(Float_t)*n;
1934
1936}
1937
1938////////////////////////////////////////////////////////////////////////////////
1939/// Write array of n bools into the I/O buffer.
1940
1942{
1943 if (n <= 0) return;
1944
1945 Int_t l = sizeof(UChar_t)*n;
1947
1948 if (sizeof(Bool_t) > 1) {
1949 for (int i = 0; i < n; i++)
1950 tobuf(fBufCur, b[i]);
1951 } else {
1952 memcpy(fBufCur, b, l);
1953 fBufCur += l;
1954 }
1955}
1956
1957////////////////////////////////////////////////////////////////////////////////
1958/// Write array of n characters into the I/O buffer.
1959
1961{
1962 if (n <= 0) return;
1963
1964 Int_t l = sizeof(Char_t)*n;
1966
1967 memcpy(fBufCur, c, l);
1968 fBufCur += l;
1969}
1970
1971////////////////////////////////////////////////////////////////////////////////
1972/// Write array of n characters into the I/O buffer.
1973
1975{
1976 if (n < 255) {
1977 *this << (UChar_t)n;
1978 } else {
1979 *this << (UChar_t)255;
1980 *this << n;
1981 }
1982
1983 if (n <= 0) return;
1984
1985 Int_t l = sizeof(Char_t)*n;
1987
1988 memcpy(fBufCur, c, l);
1989 fBufCur += l;
1990}
1991
1992////////////////////////////////////////////////////////////////////////////////
1993/// Write array of n shorts into the I/O buffer.
1994
1996{
1997 if (n <= 0) return;
1998
1999 Int_t l = sizeof(Short_t)*n;
2001
2002#ifdef R__BYTESWAP
2003# ifdef USE_BSWAPCPY
2004 bswapcpy16(fBufCur, h, n);
2005 fBufCur += l;
2006# else
2007 for (int i = 0; i < n; i++)
2008 tobuf(fBufCur, h[i]);
2009# endif
2010#else
2011 memcpy(fBufCur, h, l);
2012 fBufCur += l;
2013#endif
2014}
2015
2016////////////////////////////////////////////////////////////////////////////////
2017/// Write array of n ints into the I/O buffer.
2018
2020{
2021 if (n <= 0) return;
2022
2023 Int_t l = sizeof(Int_t)*n;
2025
2026#ifdef R__BYTESWAP
2027# ifdef USE_BSWAPCPY
2028 bswapcpy32(fBufCur, ii, n);
2029 fBufCur += l;
2030# else
2031 for (int i = 0; i < n; i++)
2032 tobuf(fBufCur, ii[i]);
2033# endif
2034#else
2035 memcpy(fBufCur, ii, l);
2036 fBufCur += l;
2037#endif
2038}
2039
2040////////////////////////////////////////////////////////////////////////////////
2041/// Write array of n longs into the I/O buffer.
2042
2044{
2045 if (n <= 0) return;
2046
2047 Int_t l = 8*n;
2049
2050 for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
2051}
2052
2053////////////////////////////////////////////////////////////////////////////////
2054/// Write array of n unsigned longs into the I/O buffer.
2055/// This is an explicit case for unsigned longs since signed longs
2056/// have a special tobuf().
2057
2059{
2060 if (n <= 0) return;
2061
2062 Int_t l = 8*n;
2064
2065 for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
2066}
2067
2068////////////////////////////////////////////////////////////////////////////////
2069/// Write array of n long longs into the I/O buffer.
2070
2072{
2073 if (n <= 0) return;
2074
2075 Int_t l = sizeof(Long64_t)*n;
2077
2078#ifdef R__BYTESWAP
2079 for (int i = 0; i < n; i++)
2080 tobuf(fBufCur, ll[i]);
2081#else
2082 memcpy(fBufCur, ll, l);
2083 fBufCur += l;
2084#endif
2085}
2086
2087////////////////////////////////////////////////////////////////////////////////
2088/// Write array of n floats into the I/O buffer.
2089
2091{
2092 if (n <= 0) return;
2093
2094 Int_t l = sizeof(Float_t)*n;
2096
2097#ifdef R__BYTESWAP
2098# ifdef USE_BSWAPCPY
2099 bswapcpy32(fBufCur, f, n);
2100 fBufCur += l;
2101# else
2102 for (int i = 0; i < n; i++)
2103 tobuf(fBufCur, f[i]);
2104# endif
2105#else
2106 memcpy(fBufCur, f, l);
2107 fBufCur += l;
2108#endif
2109}
2110
2111////////////////////////////////////////////////////////////////////////////////
2112/// Write array of n doubles into the I/O buffer.
2113
2115{
2116 if (n <= 0) return;
2117
2118 Int_t l = sizeof(Double_t)*n;
2120
2121#ifdef R__BYTESWAP
2122 for (int i = 0; i < n; i++)
2123 tobuf(fBufCur, d[i]);
2124#else
2125 memcpy(fBufCur, d, l);
2126 fBufCur += l;
2127#endif
2128}
2129
2130////////////////////////////////////////////////////////////////////////////////
2131/// Write array of n floats (as truncated float) into the I/O buffer.
2132/// see comments about Float16_t encoding at TBufferFile::WriteFloat16
2133
2135{
2136 if (n <= 0) return;
2137
2138 Int_t l = sizeof(Float_t)*n;
2140
2141 if (ele && ele->GetFactor()) {
2142 //A range is specified. We normalize the float to the range and
2143 //convert it to an integer using a scaling factor that is a function of nbits.
2144 //see TStreamerElement::GetRange.
2145 Double_t factor = ele->GetFactor();
2146 Double_t xmin = ele->GetXmin();
2147 Double_t xmax = ele->GetXmax();
2148 for (int j = 0; j < n; j++) {
2149 Float_t x = f[j];
2150 if (x < xmin) x = xmin;
2151 if (x > xmax) x = xmax;
2152 UInt_t aint = UInt_t(0.5+factor*(x-xmin)); *this << aint;
2153 }
2154 } else {
2155 Int_t nbits = 0;
2156 //number of bits stored in fXmin (see TStreamerElement::GetRange)
2157 if (ele) nbits = (Int_t)ele->GetXmin();
2158 if (!nbits) nbits = 12;
2159 Int_t i;
2160 //a range is not specified, but nbits is.
2161 //In this case we truncate the mantissa to nbits and we stream
2162 //the exponent as a UChar_t and the mantissa as a UShort_t.
2163 union {
2164 Float_t fFloatValue;
2165 Int_t fIntValue;
2166 };
2167 for (i = 0; i < n; i++) {
2168 fFloatValue = f[i];
2169 UChar_t theExp = (UChar_t)(0x000000ff & ((fIntValue<<1)>>24));
2170 UShort_t theMan = ((1<<(nbits+1))-1) & (fIntValue>>(23-nbits-1));
2171 theMan++;
2172 theMan = theMan>>1;
2173 if (theMan&1<<nbits) theMan = (1<<nbits) - 1;
2174 if (fFloatValue < 0) theMan |= 1<<(nbits+1);
2175 *this << theExp;
2176 *this << theMan;
2177 }
2178 }
2179}
2180
2181////////////////////////////////////////////////////////////////////////////////
2182/// Write array of n doubles (as float) into the I/O buffer.
2183/// see comments about Double32_t encoding at TBufferFile::WriteDouble32
2184
2186{
2187 if (n <= 0) return;
2188
2189 Int_t l = sizeof(Float_t)*n;
2191
2192 if (ele && ele->GetFactor()) {
2193 //A range is specified. We normalize the double to the range and
2194 //convert it to an integer using a scaling factor that is a function of nbits.
2195 //see TStreamerElement::GetRange.
2196 Double_t factor = ele->GetFactor();
2197 Double_t xmin = ele->GetXmin();
2198 Double_t xmax = ele->GetXmax();
2199 for (int j = 0; j < n; j++) {
2200 Double_t x = d[j];
2201 if (x < xmin) x = xmin;
2202 if (x > xmax) x = xmax;
2203 UInt_t aint = UInt_t(0.5+factor*(x-xmin)); *this << aint;
2204 }
2205 } else {
2206 Int_t nbits = 0;
2207 //number of bits stored in fXmin (see TStreamerElement::GetRange)
2208 if (ele) nbits = (Int_t)ele->GetXmin();
2209 Int_t i;
2210 if (!nbits) {
2211 //if no range and no bits specified, we convert from double to float
2212 for (i = 0; i < n; i++) {
2213 Float_t afloat = (Float_t)d[i];
2214 *this << afloat;
2215 }
2216 } else {
2217 //a range is not specified, but nbits is.
2218 //In this case we truncate the mantissa to nbits and we stream
2219 //the exponent as a UChar_t and the mantissa as a UShort_t.
2220 union {
2221 Float_t fFloatValue;
2222 Int_t fIntValue;
2223 };
2224 for (i = 0; i < n; i++) {
2225 fFloatValue = (Float_t)d[i];
2226 UChar_t theExp = (UChar_t)(0x000000ff & ((fIntValue<<1)>>24));
2227 UShort_t theMan = ((1<<(nbits+1))-1) & (fIntValue>>(23-nbits-1));
2228 theMan++;
2229 theMan = theMan>>1;
2230 if(theMan&1<<nbits) theMan = (1<<nbits) - 1;
2231 if (fFloatValue < 0) theMan |= 1<<(nbits+1);
2232 *this << theExp;
2233 *this << theMan;
2234 }
2235 }
2236 }
2237}
2238
2239////////////////////////////////////////////////////////////////////////////////
2240/// Write an array of object starting at the address 'start' and of length 'n'
2241/// the objects in the array are assumed to be of class 'cl'
2242
2243void TBufferFile::WriteFastArray(void *start, const TClass *cl, Int_t n,
2244 TMemberStreamer *streamer)
2245{
2246 if (streamer) {
2247 (*streamer)(*this, start, 0);
2248 return;
2249 }
2250
2251 char *obj = (char*)start;
2252 if (!n) n=1;
2253 int size = cl->Size();
2254
2255 for(Int_t j=0; j<n; j++,obj+=size) {
2256 ((TClass*)cl)->Streamer(obj,*this);
2257 }
2258}
2259
2260////////////////////////////////////////////////////////////////////////////////
2261/// Write an array of object starting at the address '*start' and of length 'n'
2262/// the objects in the array are of class 'cl'
2263/// 'isPreAlloc' indicates whether the data member is marked with '->'
2264/// Return:
2265/// - 0: success
2266/// - 2: truncated success (i.e actual class is missing. Only ptrClass saved.)
2267
2269 Bool_t isPreAlloc, TMemberStreamer *streamer)
2270{
2271 // if isPreAlloc is true (data member has a ->) we can assume that the pointer
2272 // is never 0.
2273
2274 if (streamer) {
2275 (*streamer)(*this,(void*)start,0);
2276 return 0;
2277 }
2278
2279 int strInfo = 0;
2280
2281 Int_t res = 0;
2282
2283 if (!isPreAlloc) {
2284
2285 for (Int_t j=0;j<n;j++) {
2286 //must write StreamerInfo if pointer is null
2287 if (!strInfo && !start[j]) {
2288 if (cl->Property() & kIsAbstract) {
2289 // Do not try to generate the StreamerInfo for an abstract class
2290 } else {
2291 TStreamerInfo *info = (TStreamerInfo*)((TClass*)cl)->GetStreamerInfo();
2292 ForceWriteInfo(info,kFALSE);
2293 }
2294 }
2295 strInfo = 2003;
2296 res |= WriteObjectAny(start[j],cl);
2297 }
2298
2299 } else {
2300 //case //-> in comment
2301
2302 for (Int_t j=0;j<n;j++) {
2303 if (!start[j]) start[j] = ((TClass*)cl)->New();
2304 ((TClass*)cl)->Streamer(start[j],*this);
2305 }
2306
2307 }
2308 return res;
2309}
2310
2311////////////////////////////////////////////////////////////////////////////////
2312/// Read object from I/O buffer. clReq is NOT used.
2313///
2314/// The value returned is the address of the actual start in memory of
2315/// the object. Note that if the actual class of the object does not
2316/// inherit first from TObject, the type of the pointer is NOT 'TObject*'.
2317/// [More accurately, the class needs to start with the TObject part, for
2318/// the pointer to be a real TObject*].
2319/// We recommend using ReadObjectAny instead of ReadObject
2320
2322{
2323 return (TObject*) ReadObjectAny(nullptr);
2324}
2325
2326////////////////////////////////////////////////////////////////////////////////
2327/// Skip any kind of object from buffer
2328
2330{
2331 UInt_t start, count;
2332 ReadVersion(&start, &count);
2333 SetBufferOffset(start+count+sizeof(UInt_t));
2334}
2335
2336////////////////////////////////////////////////////////////////////////////////
2337/// Read object from I/O buffer.
2338///
2339/// A typical use for this function is:
2340///
2341/// MyClass *ptr = (MyClass*)b.ReadObjectAny(MyClass::Class());
2342///
2343/// I.e. clCast should point to a TClass object describing the class pointed
2344/// to by your pointer.
2345/// In case of multiple inheritance, the return value might not be the
2346/// real beginning of the object in memory. You will need to use a
2347/// dynamic_cast later if you need to retrieve it.
2348
2350{
2352
2353 // make sure fMap is initialized
2354 InitMap();
2355
2356 // before reading object save start position
2357 UInt_t startpos = UInt_t(fBufCur-fBuffer);
2358
2359 // attempt to load next object as TClass clCast
2360 UInt_t tag; // either tag or byte count
2361 TClass *clRef = ReadClass(clCast, &tag);
2362 TClass *clOnfile = nullptr;
2363 Int_t baseOffset = 0;
2364 if (clRef && (clRef!=(TClass*)(-1)) && clCast) {
2365 //baseOffset will be -1 if clRef does not inherit from clCast.
2366 baseOffset = clRef->GetBaseClassOffset(clCast);
2367 if (baseOffset == -1) {
2368 // The 2 classes are unrelated, maybe there is a converter between the 2.
2369
2370 if (!clCast->GetSchemaRules() ||
2371 !clCast->GetSchemaRules()->HasRuleWithSourceClass(clRef->GetName()))
2372 {
2373 // There is no converter
2374 Error("ReadObject", "got object of wrong class! requested %s but got %s",
2375 clCast->GetName(), clRef->GetName());
2376
2377 CheckByteCount(startpos, tag, (TClass *)nullptr); // avoid mis-leading byte count error message
2378 return 0; // We better return at this point
2379 }
2380 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 ....
2381
2382 if (gDebug > 0)
2383 Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
2384 clOnfile = clRef;
2385 clRef = const_cast<TClass*>(clCast);
2386
2387 }
2388 if (clCast->GetState() > TClass::kEmulated && clRef->GetState() <= TClass::kEmulated) {
2389 //we cannot mix a compiled class with an emulated class in the inheritance
2390 Error("ReadObject", "trying to read an emulated class (%s) to store in a compiled pointer (%s)",
2391 clRef->GetName(),clCast->GetName());
2392 CheckByteCount(startpos, tag, (TClass *)nullptr); // avoid mis-leading byte count error message
2393 return 0;
2394 }
2395 }
2396
2397 // check if object has not already been read
2398 // (this can only happen when called via CheckObject())
2399 char *obj;
2400 if (fVersion > 0) {
2401 obj = (char *) (Longptr_t)fMap->GetValue(startpos+kMapOffset);
2402 if (obj == (void*) -1) obj = nullptr;
2403 if (obj) {
2404 CheckByteCount(startpos, tag, (TClass *)nullptr);
2405 return (obj + baseOffset);
2406 }
2407 }
2408
2409 // unknown class, skip to next object and return 0 obj
2410 if (clRef == (TClass*) -1) {
2411 if (fBufCur >= fBufMax) return 0;
2412 if (fVersion > 0)
2413 MapObject((TObject*) -1, startpos+kMapOffset);
2414 else
2415 MapObject((void*)nullptr, nullptr, fMapCount);
2416 CheckByteCount(startpos, tag, (TClass *)nullptr);
2417 return 0;
2418 }
2419
2420 if (!clRef) {
2421
2422 // got a reference to an already read object
2423 if (fVersion > 0) {
2424 tag += fDisplacement;
2425 tag = CheckObject(tag, clCast);
2426 } else {
2427 if (tag > (UInt_t)fMap->GetSize()) {
2428 Error("ReadObject", "object tag too large, I/O buffer corrupted");
2429 return 0;
2430 // exception
2431 }
2432 }
2433 obj = (char *) (Longptr_t)fMap->GetValue(tag);
2434 clRef = (TClass*) (Longptr_t)fClassMap->GetValue(tag);
2435
2436 if (clRef && (clRef!=(TClass*)(-1)) && clCast) {
2437 //baseOffset will be -1 if clRef does not inherit from clCast.
2438 baseOffset = clRef->GetBaseClassOffset(clCast);
2439 if (baseOffset == -1) {
2440 Error("ReadObject", "Got object of wrong class (Got %s while expecting %s)",
2441 clRef->GetName(),clCast->GetName());
2442 // exception
2443 baseOffset = 0;
2444 }
2445 }
2446
2447 // There used to be a warning printed here when:
2448 // obj && isTObject && !((TObject*)obj)->IsA()->InheritsFrom(clReq)
2449 // however isTObject was based on clReq (now clCast).
2450 // If the test was to fail, then it is as likely that the object is not a TObject
2451 // and then we have a potential core dump.
2452 // At this point (missing clRef), we do NOT have enough information to really
2453 // answer the question: is the object read of the type I requested.
2454
2455 } else {
2456
2457 // allocate a new object based on the class found
2458 obj = (char*)clRef->New();
2459 if (!obj) {
2460 Error("ReadObject", "could not create object of class %s",
2461 clRef->GetName());
2462 // exception
2463 return 0;
2464 }
2465
2466 // add to fMap before reading rest of object
2467 if (fVersion > 0)
2468 MapObject(obj, clRef, startpos+kMapOffset);
2469 else
2470 MapObject(obj, clRef, fMapCount);
2471
2472 // let the object read itself
2473 clRef->Streamer( obj, *this, clOnfile );
2474
2475 CheckByteCount(startpos, tag, clRef);
2476 }
2477
2478 return obj+baseOffset;
2479}
2480
2481////////////////////////////////////////////////////////////////////////////////
2482/// Write object to I/O buffer.
2483/// This function assumes that the value of 'actualObjectStart' is the actual start of
2484/// the object of class 'actualClass'
2485/// If 'cacheReuse' is true (default) upon seeing an object address a second time,
2486/// we record the offset where its was written the first time rather than streaming
2487/// the object a second time.
2488/// If 'cacheReuse' is false, we always stream the object. This allows the (re)use
2489/// of temporary object to store different data in the same buffer.
2490
2491void TBufferFile::WriteObjectClass(const void *actualObjectStart, const TClass *actualClass, Bool_t cacheReuse)
2492{
2494
2495 if (!actualObjectStart) {
2496
2497 // save kNullTag to represent NULL pointer
2498 *this << (UInt_t) kNullTag;
2499
2500 } else {
2501
2502 // make sure fMap is initialized
2503 InitMap();
2504
2505 ULongptr_t idx;
2506 UInt_t slot;
2507 ULong_t hash = Void_Hash(actualObjectStart);
2508
2509 if ((idx = (ULongptr_t)fMap->GetValue(hash, (Longptr_t)actualObjectStart, slot)) != 0) {
2510
2511 // truncation is OK the value we did put in the map is an 30-bit offset
2512 // and not a pointer
2513 UInt_t objIdx = UInt_t(idx);
2514
2515 // save index of already stored object
2516 *this << objIdx;
2517
2518 } else {
2519
2520 // A warning to let the user know it will need to change the class code
2521 // to be able to read this back.
2522 if (!actualClass->HasDefaultConstructor(kTRUE)) {
2523 Warning("WriteObjectAny", "since %s has no public constructor\n"
2524 "\twhich can be called without argument, objects of this class\n"
2525 "\tcan not be read with the current library. You will need to\n"
2526 "\tadd a default constructor before attempting to read it.",
2527 actualClass->GetName());
2528 }
2529
2530 // reserve space for leading byte count
2531 UInt_t cntpos = UInt_t(fBufCur-fBuffer);
2532 fBufCur += sizeof(UInt_t);
2533
2534 // write class of object first
2535 Int_t mapsize = fMap->Capacity(); // The slot depends on the capacity and WriteClass might induce an increase.
2536 WriteClass(actualClass);
2537
2538 if (cacheReuse) {
2539 // add to map before writing rest of object (to handle self reference)
2540 // (+kMapOffset so it's != kNullTag)
2541 //MapObject(actualObjectStart, actualClass, cntpos+kMapOffset);
2542 UInt_t offset = cntpos+kMapOffset;
2543 if (mapsize == fMap->Capacity()) {
2544 fMap->AddAt(slot, hash, (Longptr_t)actualObjectStart, offset);
2545 } else {
2546 // The slot depends on the capacity and WriteClass has induced an increase.
2547 fMap->Add(hash, (Longptr_t)actualObjectStart, offset);
2548 }
2549 // No need to keep track of the class in write mode
2550 // fClassMap->Add(hash, (Long_t)obj, (Long_t)((TObject*)obj)->IsA());
2551 fMapCount++;
2552 }
2553
2554 ((TClass*)actualClass)->Streamer((void*)actualObjectStart,*this);
2555
2556 // write byte count
2557 SetByteCount(cntpos);
2558 }
2559 }
2560}
2561
2562////////////////////////////////////////////////////////////////////////////////
2563/// Read class definition from I/O buffer.
2564///
2565/// \param[in] clReq Can be used to cross check if the actually read object is of the requested class.
2566/// \param[in] objTag Set in case the object is a reference to an already read object.
2567
2569{
2571
2572 // read byte count and/or tag (older files don't have byte count)
2573 TClass *cl;
2574 if (fBufCur < fBuffer || fBufCur > fBufMax) {
2575 fBufCur = fBufMax;
2576 cl = (TClass*)-1;
2577 return cl;
2578 }
2579 UInt_t bcnt, tag, startpos = 0;
2580 *this >> bcnt;
2581 if (!(bcnt & kByteCountMask) || bcnt == kNewClassTag) {
2582 tag = bcnt;
2583 bcnt = 0;
2584 } else {
2585 fVersion = 1;
2586 startpos = UInt_t(fBufCur-fBuffer);
2587 *this >> tag;
2588 }
2589
2590 // in case tag is object tag return tag
2591 if (!(tag & kClassMask)) {
2592 if (objTag) *objTag = tag;
2593 return 0;
2594 }
2595
2596 if (tag == kNewClassTag) {
2597
2598 // got a new class description followed by a new object
2599 // (class can be 0 if class dictionary is not found, in that
2600 // case object of this class must be skipped)
2601 cl = TClass::Load(*this);
2602
2603 // add class to fMap for later reference
2604 if (fVersion > 0) {
2605 // check if class was already read
2606 TClass *cl1 = (TClass *)(Longptr_t)fMap->GetValue(startpos+kMapOffset);
2607 if (cl1 != cl)
2608 MapObject(cl ? cl : (TObject*) -1, startpos+kMapOffset);
2609 } else
2610 MapObject(cl, fMapCount);
2611
2612 } else {
2613
2614 // got a tag to an already seen class
2615 UInt_t clTag = (tag & ~kClassMask);
2616
2617 if (fVersion > 0) {
2618 clTag += fDisplacement;
2619 clTag = CheckObject(clTag, clReq, kTRUE);
2620 } else {
2621 if (clTag == 0 || clTag > (UInt_t)fMap->GetSize()) {
2622 Error("ReadClass", "illegal class tag=%d (0<tag<=%d), I/O buffer corrupted",
2623 clTag, fMap->GetSize());
2624 // exception
2625 }
2626 }
2627
2628 // class can be 0 if dictionary was not found
2629 cl = (TClass *)(Longptr_t)fMap->GetValue(clTag);
2630 }
2631
2632 if (cl && clReq &&
2633 (!cl->InheritsFrom(clReq) &&
2634 !(clReq->GetSchemaRules() &&
2636 ) ) {
2637 Error("ReadClass", "The on-file class is \"%s\" which is not compatible with the requested class: \"%s\"",
2638 cl->GetName(), clReq->GetName());
2639 // exception
2640 }
2641
2642 // return bytecount in objTag
2643 if (objTag) *objTag = (bcnt & ~kByteCountMask);
2644
2645 // case of unknown class
2646 if (!cl) cl = (TClass*)-1;
2647
2648 return cl;
2649}
2650
2651////////////////////////////////////////////////////////////////////////////////
2652/// Write class description to I/O buffer.
2653
2655{
2657
2658 ULongptr_t idx;
2659 ULong_t hash = Void_Hash(cl);
2660 UInt_t slot;
2661
2662 if ((idx = (ULongptr_t)fMap->GetValue(hash, (Longptr_t)cl,slot)) != 0) {
2663
2664 // truncation is OK the value we did put in the map is an 30-bit offset
2665 // and not a pointer
2666 UInt_t clIdx = UInt_t(idx);
2667
2668 // save index of already stored class
2669 *this << (clIdx | kClassMask);
2670
2671 } else {
2672
2673 // offset in buffer where class info is written
2675
2676 // save new class tag
2677 *this << kNewClassTag;
2678
2679 // write class name
2680 cl->Store(*this);
2681
2682 // store new class reference in fMap (+kMapOffset so it's != kNullTag)
2684 fMap->AddAt(slot, hash, (Longptr_t)cl, offset+kMapOffset);
2685 fMapCount++;
2686 }
2687}
2688
2689////////////////////////////////////////////////////////////////////////////////
2690/// Skip class version from I/O buffer.
2691
2693{
2694 Version_t version;
2695
2696 // not interested in byte count
2697 frombuf(this->fBufCur,&version);
2698
2699 // if this is a byte count, then skip next short and read version
2700 if (version & kByteCountVMask) {
2701 frombuf(this->fBufCur,&version);
2702 frombuf(this->fBufCur,&version);
2703 }
2704
2705 if (cl && cl->GetClassVersion() != 0 && version<=1) {
2706 if (version <= 0) {
2707 UInt_t checksum = 0;
2708 //*this >> checksum;
2709 frombuf(this->fBufCur,&checksum);
2710 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2711 if (vinfo) {
2712 return;
2713 } else {
2714 // There are some cases (for example when the buffer was stored outside of
2715 // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2716 // the one from the current class, we can still assume that we can read
2717 // the data so let use it.
2718 if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2719 version = cl->GetClassVersion();
2720 } else {
2721 if (fParent) {
2722 Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
2723 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2724 } else {
2725 Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" (buffer with no parent)",
2726 checksum, cl->GetName());
2727 }
2728 return;
2729 }
2730 }
2731 } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 ) {
2732 // We could have a file created using a Foreign class before
2733 // the introduction of the CheckSum. We need to check
2734 if ((!cl->IsLoaded() || cl->IsForeign()) &&
2736
2737 const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2738 const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2739 if ( local ) {
2740 UInt_t checksum = local->GetCheckSum();
2741 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2742 if (vinfo) {
2743 version = vinfo->GetClassVersion();
2744 } else {
2745 Error("SkipVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
2746 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2747 return;
2748 }
2749 }
2750 else {
2751 Error("SkipVersion", "Class %s not known to file %s.",
2752 cl->GetName(), ((TFile*)fParent)->GetName());
2753 version = 0;
2754 }
2755 }
2756 }
2757 }
2758}
2759
2760////////////////////////////////////////////////////////////////////////////////
2761/// Read class version from I/O buffer.
2762
2764{
2765 Version_t version;
2766
2767 if (startpos) {
2768 // before reading object save start position
2769 *startpos = UInt_t(fBufCur-fBuffer);
2770 }
2771
2772 // read byte count (older files don't have byte count)
2773 // byte count is packed in two individual shorts, this to be
2774 // backward compatible with old files that have at this location
2775 // only a single short (i.e. the version)
2776 union {
2777 UInt_t cnt;
2778 Version_t vers[2];
2779 } v;
2780#ifdef R__BYTESWAP
2781 frombuf(this->fBufCur,&v.vers[1]);
2782 frombuf(this->fBufCur,&v.vers[0]);
2783#else
2784 frombuf(this->fBufCur,&v.vers[0]);
2785 frombuf(this->fBufCur,&v.vers[1]);
2786#endif
2787
2788 // no bytecount, backup and read version
2789 if (!(v.cnt & kByteCountMask)) {
2790 fBufCur -= sizeof(UInt_t);
2791 v.cnt = 0;
2792 }
2793 if (bcnt) *bcnt = (v.cnt & ~kByteCountMask);
2794 frombuf(this->fBufCur,&version);
2795
2796 if (version<=1) {
2797 if (version <= 0) {
2798 if (cl) {
2799 if (cl->GetClassVersion() != 0
2800 // If v.cnt < 6 then we have a class with a version that used to be zero and so there is no checksum.
2801 && (v.cnt && v.cnt >= 6)
2802 ) {
2803 UInt_t checksum = 0;
2804 //*this >> checksum;
2805 frombuf(this->fBufCur,&checksum);
2806 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2807 if (vinfo) {
2808 return vinfo->TStreamerInfo::GetClassVersion(); // Try to get inlining.
2809 } else {
2810 // There are some cases (for example when the buffer was stored outside of
2811 // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2812 // the one from the current class, we can still assume that we can read
2813 // the data so let use it.
2814 if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2815 version = cl->GetClassVersion();
2816 } else {
2817 if (fParent) {
2818 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" in %s.",
2819 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2820 } else {
2821 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" (buffer with no parent)",
2822 checksum, cl->GetName());
2823 }
2824 return 0;
2825 }
2826 }
2827 }
2828 } else { // of if (cl) {
2829 UInt_t checksum = 0;
2830 //*this >> checksum;
2831 // If *bcnt < 6 then we have a class with 'just' version zero and no checksum
2832 if (v.cnt && v.cnt >= 6)
2833 frombuf(this->fBufCur,&checksum);
2834 }
2835 } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 && cl && cl->GetClassVersion() != 0) {
2836 // We could have a file created using a Foreign class before
2837 // the introduction of the CheckSum. We need to check
2838 if ((!cl->IsLoaded() || cl->IsForeign()) &&
2840
2841 const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2842 const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2843 if ( local ) {
2844 UInt_t checksum = local->GetCheckSum();
2845 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2846 if (vinfo) {
2847 version = vinfo->GetClassVersion();
2848 } else {
2849 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of 0x%x for the class \"%s\" in %s.",
2850 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
2851 return 0;
2852 }
2853 }
2854 else {
2855 Error("ReadVersion", "Class %s not known to file %s.",
2856 cl->GetName(), ((TFile*)fParent)->GetName());
2857 version = 0;
2858 }
2859 }
2860 }
2861 }
2862 return version;
2863}
2864
2865////////////////////////////////////////////////////////////////////////////////
2866/// Read class version from I/O buffer, when the caller knows for sure that
2867/// there is no checksum written/involved.
2868
2870{
2871 Version_t version;
2872
2873 if (startpos) {
2874 // before reading object save start position
2875 *startpos = UInt_t(fBufCur-fBuffer);
2876 }
2877
2878 // read byte count (older files don't have byte count)
2879 // byte count is packed in two individual shorts, this to be
2880 // backward compatible with old files that have at this location
2881 // only a single short (i.e. the version)
2882 union {
2883 UInt_t cnt;
2884 Version_t vers[2];
2885 } v;
2886#ifdef R__BYTESWAP
2887 frombuf(this->fBufCur,&v.vers[1]);
2888 frombuf(this->fBufCur,&v.vers[0]);
2889#else
2890 frombuf(this->fBufCur,&v.vers[0]);
2891 frombuf(this->fBufCur,&v.vers[1]);
2892#endif
2893
2894 // no bytecount, backup and read version
2895 if (!(v.cnt & kByteCountMask)) {
2896 fBufCur -= sizeof(UInt_t);
2897 v.cnt = 0;
2898 }
2899 if (bcnt) *bcnt = (v.cnt & ~kByteCountMask);
2900 frombuf(this->fBufCur,&version);
2901
2902 return version;
2903}
2904
2905////////////////////////////////////////////////////////////////////////////////
2906/// Read class version from I/O buffer
2907///
2908/// To be used when streaming out member-wise streamed collection where we do not
2909/// care (not save) about the byte count and can safely ignore missing streamerInfo
2910/// (since they usually indicate empty collections).
2911
2913{
2914 Version_t version;
2915
2916 // not interested in byte count
2917 frombuf(this->fBufCur,&version);
2918
2919 if (version<=1) {
2920 if (version <= 0) {
2921 if (cl) {
2922 if (cl->GetClassVersion() != 0) {
2923 UInt_t checksum = 0;
2924 frombuf(this->fBufCur,&checksum);
2925 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2926 if (vinfo) {
2927 return vinfo->TStreamerInfo::GetClassVersion(); // Try to get inlining.
2928 } else {
2929 // There are some cases (for example when the buffer was stored outside of
2930 // a ROOT file) where we do not have a TStreamerInfo. If the checksum is
2931 // the one from the current class, we can still assume that we can read
2932 // the data so let use it.
2933 if (checksum==cl->GetCheckSum() || cl->MatchLegacyCheckSum(checksum)) {
2934 version = cl->GetClassVersion();
2935 } else {
2936 // If we can not find the streamerInfo this means that
2937 // we do not actually need it (the collection is always empty
2938 // in this file), so no need to issue a warning.
2939 return 0;
2940 }
2941 }
2942 }
2943 } else { // of if (cl) {
2944 UInt_t checksum = 0;
2945 frombuf(this->fBufCur,&checksum);
2946 }
2947 } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 && cl && cl->GetClassVersion() != 0) {
2948 // We could have a file created using a Foreign class before
2949 // the introduction of the CheckSum. We need to check
2950 if ((!cl->IsLoaded() || cl->IsForeign()) && Class_Has_StreamerInfo(cl) ) {
2951
2952 const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
2953 const TStreamerInfo *local = list ? (TStreamerInfo*)list->FindObject(cl->GetName()) : 0;
2954 if ( local ) {
2955 UInt_t checksum = local->GetCheckSum();
2956 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
2957 if (vinfo) {
2958 version = vinfo->GetClassVersion();
2959 } else {
2960 // If we can not find the streamerInfo this means that
2961 // we do not actually need it (the collection is always empty
2962 // in this file), so no need to issue a warning.
2963 return 0;
2964 }
2965 }
2966 else {
2967 Error("ReadVersion", "Class %s not known to file %s.",
2968 cl->GetName(), ((TFile*)fParent)->GetName());
2969 version = 0;
2970 }
2971 }
2972 }
2973 }
2974 return version;
2975}
2976
2977////////////////////////////////////////////////////////////////////////////////
2978/// Write class version to I/O buffer.
2979
2981{
2982 UInt_t cntpos = 0;
2983 if (useBcnt) {
2984 // reserve space for leading byte count
2985 cntpos = UInt_t(fBufCur-fBuffer);
2986 fBufCur += sizeof(UInt_t);
2987 }
2988
2989 Version_t version = cl->GetClassVersion();
2990 if (version<=1 && cl->IsForeign()) {
2991 *this << Version_t(0);
2992 *this << cl->GetCheckSum();
2993 } else {
2994 if (version > kMaxVersion) {
2995 Error("WriteVersion", "version number cannot be larger than %hd)",
2996 kMaxVersion);
2997 version = kMaxVersion;
2998 }
2999 *this <<version;
3000 }
3001
3002 // return position where to store possible byte count
3003 return cntpos;
3004}
3005
3006////////////////////////////////////////////////////////////////////////////////
3007/// Write class version to I/O buffer after setting the kStreamedMemberWise
3008/// bit in the version number.
3009
3011{
3012 UInt_t cntpos = 0;
3013 if (useBcnt) {
3014 // reserve space for leading byte count
3015 cntpos = UInt_t(fBufCur-fBuffer);
3016 fBufCur += sizeof(UInt_t);
3017 }
3018
3019 Version_t version = cl->GetClassVersion();
3020 if (version<=1 && cl->IsForeign()) {
3021 Error("WriteVersionMemberWise", "Member-wise streaming of foreign collection not yet implemented!");
3022 *this << Version_t(0);
3023 *this << cl->GetCheckSum();
3024 } else {
3025 if (version > kMaxVersion) {
3026 Error("WriteVersionMemberWise", "version number cannot be larger than %hd)",
3027 kMaxVersion);
3028 version = kMaxVersion;
3029 }
3030 version |= kStreamedMemberWise;
3031 *this <<version;
3032 }
3033
3034 // return position where to store possible byte count
3035 return cntpos;
3036}
3037
3038////////////////////////////////////////////////////////////////////////////////
3039/// Stream an object given its C++ typeinfo information.
3040
3041void TBufferFile::StreamObject(void *obj, const std::type_info &typeinfo, const TClass* onFileClass )
3042{
3043 TClass *cl = TClass::GetClass(typeinfo);
3044 if (cl) cl->Streamer(obj, *this, (TClass*)onFileClass );
3045 else Warning("StreamObject","No TClass for the type %s is available, the object was not read.", typeinfo.name());
3046}
3047
3048////////////////////////////////////////////////////////////////////////////////
3049/// Stream an object given the name of its actual class.
3050
3051void TBufferFile::StreamObject(void *obj, const char *className, const TClass* onFileClass)
3052{
3053 TClass *cl = TClass::GetClass(className);
3054 if (cl) cl->Streamer(obj, *this, (TClass*)onFileClass );
3055 else Warning("StreamObject","No TClass for the type %s is available, the object was not read.", className);
3056}
3057
3058////////////////////////////////////////////////////////////////////////////////
3059/// Stream an object given a pointer to its actual class.
3060
3061void TBufferFile::StreamObject(void *obj, const TClass *cl, const TClass* onFileClass )
3062{
3063 ((TClass*)cl)->Streamer(obj, *this, (TClass*)onFileClass );
3064}
3065
3066////////////////////////////////////////////////////////////////////////////////
3067/// Stream an object inheriting from TObject using its streamer.
3068
3070{
3071 obj->Streamer(*this);
3072}
3073
3074////////////////////////////////////////////////////////////////////////////////
3075/// Check if offset is not too large (< kMaxMapCount) when writing.
3076
3078{
3079 if (IsWriting()) {
3080 if (offset >= kMaxMapCount) {
3081 Error("CheckCount", "buffer offset too large (larger than %d)", kMaxMapCount);
3082 // exception
3083 }
3084 }
3085}
3086
3087////////////////////////////////////////////////////////////////////////////////
3088/// Check for object in the read map. If the object is 0 it still has to be
3089/// read. Try to read it from the buffer starting at location offset. If the
3090/// object is -1 then it really does not exist and we return 0. If the object
3091/// exists just return the offset.
3092
3094{
3095 // in position 0 we always have the reference to the null object
3096 if (!offset) return offset;
3097
3098 Longptr_t cli;
3099
3100 if (readClass) {
3101 if ((cli = fMap->GetValue(offset)) == 0) {
3102 // No class found at this location in map. It might have been skipped
3103 // as part of a skipped object. Try to explicitly read the class.
3104
3105 // save fBufCur and set to place specified by offset (-kMapOffset-sizeof(bytecount))
3106 char *bufsav = fBufCur;
3107 fBufCur = (char *)(fBuffer + offset-kMapOffset-sizeof(UInt_t));
3108
3109 TClass *c = ReadClass(cl);
3110 if (c == (TClass*) -1) {
3111 // mark class as really not available
3112 fMap->Remove(offset);
3113 fMap->Add(offset, -1);
3114 offset = 0;
3115 if (cl)
3116 Warning("CheckObject", "reference to unavailable class %s,"
3117 " pointers of this type will be 0", cl->GetName());
3118 else
3119 Warning("CheckObject", "reference to an unavailable class,"
3120 " pointers of that type will be 0");
3121 }
3122
3123 fBufCur = bufsav;
3124
3125 } else if (cli == -1) {
3126
3127 // class really does not exist
3128 return 0;
3129 }
3130
3131 } else {
3132
3133 if ((cli = fMap->GetValue(offset)) == 0) {
3134 // No object found at this location in map. It might have been skipped
3135 // as part of a skipped object. Try to explicitly read the object.
3136
3137 // save fBufCur and set to place specified by offset (-kMapOffset)
3138 char *bufsav = fBufCur;
3139 fBufCur = (char *)(fBuffer + offset-kMapOffset);
3140
3141 TObject *obj = ReadObject(cl);
3142 if (!obj) {
3143 // mark object as really not available
3144 fMap->Remove(offset);
3145 fMap->Add(offset, -1);
3146 Warning("CheckObject", "reference to object of unavailable class %s, offset=%d"
3147 " pointer will be 0", cl ? cl->GetName() : "TObject",offset);
3148 offset = 0;
3149 }
3150
3151 fBufCur = bufsav;
3152
3153 } else if (cli == -1) {
3154
3155 // object really does not exist
3156 return 0;
3157 }
3158
3159 }
3160
3161 return offset;
3162}
3163
3164
3165////////////////////////////////////////////////////////////////////////////////
3166/// Read max bytes from the I/O buffer into buf. The function returns
3167/// the actual number of bytes read.
3168
3170{
3172
3173 if (max == 0) return 0;
3174
3175 Int_t n = TMath::Min(max, (Int_t)(fBufMax - fBufCur));
3176
3177 memcpy(buf, fBufCur, n);
3178 fBufCur += n;
3179
3180 return n;
3181}
3182
3183////////////////////////////////////////////////////////////////////////////////
3184/// Write max bytes from buf into the I/O buffer.
3185
3186void TBufferFile::WriteBuf(const void *buf, Int_t max)
3187{
3189
3190 if (max == 0) return;
3191
3192 if (fBufCur + max > fBufMax) AutoExpand(fBufSize+max); // a more precise request would be: fBufSize + max - (fBufMax - fBufCur)
3193
3194 memcpy(fBufCur, buf, max);
3195 fBufCur += max;
3196}
3197
3198////////////////////////////////////////////////////////////////////////////////
3199/// Read string from I/O buffer. String is read till 0 character is
3200/// found or till max-1 characters are read (i.e. string s has max
3201/// bytes allocated). If max = -1 no check on number of character is
3202/// made, reading continues till 0 character is found.
3203
3205{
3207
3208 char ch;
3209 Int_t nr = 0;
3210
3211 if (max == -1) max = kMaxInt;
3212
3213 while (nr < max-1) {
3214
3215 *this >> ch;
3216
3217 // stop when 0 read
3218 if (ch == 0) break;
3219
3220 s[nr++] = ch;
3221 }
3222
3223 s[nr] = 0;
3224 return s;
3225}
3226
3227////////////////////////////////////////////////////////////////////////////////
3228/// Write string to I/O buffer. Writes string upto and including the
3229/// terminating 0.
3230
3231void TBufferFile::WriteString(const char *s)
3232{
3233 WriteBuf(s, (strlen(s)+1)*sizeof(char));
3234}
3235
3236////////////////////////////////////////////////////////////////////////////////
3237/// Read emulated class.
3238
3239Int_t TBufferFile::ReadClassEmulated(const TClass *cl, void *object, const TClass *onFileClass)
3240{
3241 UInt_t start,count;
3242 //We assume that the class was written with a standard streamer
3243 //We attempt to recover if a version count was not written
3244 Version_t v = ReadVersion(&start,&count);
3245
3246 if (count) {
3247 TStreamerInfo *sinfo = nullptr;
3248 if( onFileClass ) {
3249 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, v );
3250 if( !sinfo )
3251 return 0;
3252 }
3253
3254 sinfo = (TStreamerInfo*)cl->GetStreamerInfo(v);
3255 ApplySequence(*(sinfo->GetReadObjectWiseActions()), object);
3256 if (sinfo->IsRecovered()) count=0;
3257 CheckByteCount(start,count,cl);
3258 } else {
3259 SetBufferOffset(start);
3260 TStreamerInfo *sinfo = ((TStreamerInfo*)cl->GetStreamerInfo());
3261 ApplySequence(*(sinfo->GetReadObjectWiseActions()), object);
3262 }
3263 return 0;
3264}
3265
3266////////////////////////////////////////////////////////////////////////////////
3267/// Deserialize information from a buffer into an object.
3268///
3269/// Note: This function is called by the xxx::Streamer() functions in
3270/// rootcint-generated dictionaries.
3271/// This function assumes that the class version and the byte count
3272/// information have been read.
3273///
3274/// \param[in] cl pointer to the local TClass
3275/// \param[out] pointer void pointer to object
3276/// \param[in] version The version number of the class
3277/// \param[in] start The starting position in the buffer b
3278/// \param[in] count The number of bytes for this object in the buffer
3279/// \param[in] onFileClass pointer to TClass object on file
3280///
3281
3282Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, Int_t version, UInt_t start, UInt_t count, const TClass *onFileClass)
3283{
3284
3285 //---------------------------------------------------------------------------
3286 // The ondisk class has been specified so get foreign streamer info
3287 /////////////////////////////////////////////////////////////////////////////
3288
3289 TStreamerInfo *sinfo = nullptr;
3290 if( onFileClass ) {
3291 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, version );
3292 if( !sinfo ) {
3293 Error("ReadClassBuffer",
3294 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
3295 onFileClass->GetName(), version, cl->GetName(), Length() );
3296 CheckByteCount(start, count, onFileClass);
3297 return 0;
3298 }
3299 }
3300 //---------------------------------------------------------------------------
3301 // Get local streamer info
3302 /////////////////////////////////////////////////////////////////////////////
3303 /// The StreamerInfo should exist at this point.
3304
3305 else {
3307 auto infos = cl->GetStreamerInfos();
3308 auto ninfos = infos->GetSize();
3309 if (version < -1 || version >= ninfos) {
3310 Error("ReadClassBuffer", "class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
3311 cl->GetName(), version, Length() );
3312 CheckByteCount(start, count, cl);
3313 return 0;
3314 }
3315 sinfo = (TStreamerInfo*)infos->At(version);
3316 if (sinfo == nullptr) {
3317 // Unless the data is coming via a socket connection from with schema evolution
3318 // (tracking) was not enabled. So let's create the StreamerInfo if it is the
3319 // one for the current version, otherwise let's complain ...
3320 // We could also get here if there old class version was '1' and the new class version is higher than 1
3321 // AND the checksum is the same.
3323 // check if another thread took care of this already
3324 sinfo = (TStreamerInfo*)cl->GetStreamerInfos()->At(version);
3325 if (sinfo == nullptr) {
3326 if ( version == cl->GetClassVersion() || version == 1 ) {
3327 const_cast<TClass*>(cl)->BuildRealData(pointer);
3328 // This creation is alright since we just checked within the
3329 // current 'locked' section.
3330 sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
3331 const_cast<TClass*>(cl)->RegisterStreamerInfo(sinfo);
3332 if (gDebug > 0) Info("ReadClassBuffer", "Creating StreamerInfo for class: %s, version: %d", cl->GetName(), version);
3333 sinfo->Build();
3334 } else if (version==0) {
3335 // When the object was written the class was version zero, so
3336 // there is no StreamerInfo to be found.
3337 // Check that the buffer position corresponds to the byte count.
3338 CheckByteCount(start, count, cl);
3339 return 0;
3340 } else {
3341 Error("ReadClassBuffer", "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
3342 version, cl->GetName(), Length() );
3343 CheckByteCount(start, count, cl);
3344 return 0;
3345 }
3346 }
3347 } else if (!sinfo->IsCompiled()) { // Note this read is protected by the above lock.
3348 // Streamer info has not been compiled, but exists.
3349 // Therefore it was read in from a file and we have to do schema evolution.
3351 // check if another thread took care of this already
3352 if (!sinfo->IsCompiled()) {
3353 const_cast<TClass*>(cl)->BuildRealData(pointer);
3354 sinfo->BuildOld();
3355 }
3356 }
3357 }
3358
3359 // Deserialize the object.
3360 ApplySequence(*(sinfo->GetReadObjectWiseActions()), (char*)pointer);
3361 if (sinfo->IsRecovered()) count=0;
3362
3363 // Check that the buffer position corresponds to the byte count.
3364 CheckByteCount(start, count, cl);
3365 return 0;
3366}
3367
3368////////////////////////////////////////////////////////////////////////////////
3369/// Deserialize information from a buffer into an object.
3370///
3371/// Note: This function is called by the xxx::Streamer()
3372/// functions in rootcint-generated dictionaries.
3373///
3374
3375Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onFileClass)
3376{
3377 // Read the class version from the buffer.
3378 UInt_t R__s = 0; // Start of object.
3379 UInt_t R__c = 0; // Count of bytes.
3380 Version_t version;
3381
3382 if( onFileClass )
3383 version = ReadVersion(&R__s, &R__c, onFileClass);
3384 else
3385 version = ReadVersion(&R__s, &R__c, cl);
3386
3387 Bool_t v2file = kFALSE;
3388 TFile *file = (TFile*)GetParent();
3389 if (file && file->GetVersion() < 30000) {
3390 version = -1; //This is old file
3391 v2file = kTRUE;
3392 }
3393
3394 //---------------------------------------------------------------------------
3395 // The ondisk class has been specified so get foreign streamer info
3396 /////////////////////////////////////////////////////////////////////////////
3397
3398 TStreamerInfo *sinfo = nullptr;
3399 if( onFileClass ) {
3400 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, version );
3401 if( !sinfo ) {
3402 Error("ReadClassBuffer",
3403 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
3404 onFileClass->GetName(), version, cl->GetName(), Length() );
3405 CheckByteCount(R__s, R__c, onFileClass);
3406 return 0;
3407 }
3408 }
3409 //---------------------------------------------------------------------------
3410 // Get local streamer info
3411 /////////////////////////////////////////////////////////////////////////////
3412 /// The StreamerInfo should exist at this point.
3413
3414 else {
3416 if (guess && guess->GetClassVersion() == version) {
3417 sinfo = guess;
3418 } else {
3419 // The last one is not the one we are looking for.
3420 {
3422
3423 const TObjArray *infos = cl->GetStreamerInfos();
3424 Int_t infocapacity = infos->Capacity();
3425 if (infocapacity) {
3426 if (version < -1 || version >= infocapacity) {
3427 Error("ReadClassBuffer","class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
3428 cl->GetName(), version, Length());
3429 CheckByteCount(R__s, R__c, cl);
3430 return 0;
3431 }
3432 sinfo = (TStreamerInfo*) infos->UncheckedAt(version);
3433 if (sinfo) {
3434 if (!sinfo->IsCompiled())
3435 {
3436 // Streamer info has not been compiled, but exists.
3437 // Therefore it was read in from a file and we have to do schema evolution?
3439 const_cast<TClass*>(cl)->BuildRealData(pointer);
3440 sinfo->BuildOld();
3441 }
3442 // If the compilation succeeded, remember this StreamerInfo.
3443 // const_cast okay because of the lock on gInterpreterMutex.
3444 if (sinfo->IsCompiled()) const_cast<TClass*>(cl)->SetLastReadInfo(sinfo);
3445 }
3446 }
3447 }
3448
3449 if (sinfo == nullptr) {
3450 // Unless the data is coming via a socket connection from with schema evolution
3451 // (tracking) was not enabled. So let's create the StreamerInfo if it is the
3452 // one for the current version, otherwise let's complain ...
3453 // We could also get here when reading a file prior to the introduction of StreamerInfo.
3454 // We could also get here if there old class version was '1' and the new class version is higher than 1
3455 // AND the checksum is the same.
3456 if (v2file || version == cl->GetClassVersion() || version == 1 ) {
3458
3459 // We need to check if another thread did not get here first
3460 // and did the StreamerInfo creation already.
3461 auto infos = cl->GetStreamerInfos();
3462 auto ninfos = infos->GetSize();
3463 if (!(version < -1 || version >= ninfos)) {
3464 sinfo = (TStreamerInfo *) infos->At(version);
3465 }
3466 if (!sinfo) {
3467 const_cast<TClass *>(cl)->BuildRealData(pointer);
3468 sinfo = new TStreamerInfo(const_cast<TClass *>(cl));
3469 sinfo->SetClassVersion(version);
3470 const_cast<TClass *>(cl)->RegisterStreamerInfo(sinfo);
3471 if (gDebug > 0)
3472 Info("ReadClassBuffer", "Creating StreamerInfo for class: %s, version: %d",
3473 cl->GetName(), version);
3474 if (v2file) {
3475 sinfo->Build(); // Get the elements.
3476 sinfo->Clear("build"); // Undo compilation.
3477 sinfo->BuildEmulated(file); // Fix the types and redo compilation.
3478 } else {
3479 sinfo->Build();
3480 }
3481 }
3482 } else if (version==0) {
3483 // When the object was written the class was version zero, so
3484 // there is no StreamerInfo to be found.
3485 // Check that the buffer position corresponds to the byte count.
3486 CheckByteCount(R__s, R__c, cl);
3487 return 0;
3488 } else {
3489 Error( "ReadClassBuffer", "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
3490 version, cl->GetName(), Length() );
3491 CheckByteCount(R__s, R__c, cl);
3492 return 0;
3493 }
3494 }
3495 }
3496 }
3497
3498 //deserialize the object
3499 ApplySequence(*(sinfo->GetReadObjectWiseActions()), (char*)pointer );
3500 if (sinfo->TStreamerInfo::IsRecovered()) R__c=0; // 'TStreamerInfo::' avoids going via a virtual function.
3501
3502 // Check that the buffer position corresponds to the byte count.
3503 CheckByteCount(R__s, R__c, cl);
3504
3505 if (gDebug > 2) Info("ReadClassBuffer", "For class: %s has read %d bytes", cl->GetName(), R__c);
3506
3507 return 0;
3508}
3509
3510////////////////////////////////////////////////////////////////////////////////
3511/// Function called by the Streamer functions to serialize object at p
3512/// to buffer b. The optional argument info may be specified to give an
3513/// alternative StreamerInfo instead of using the default StreamerInfo
3514/// automatically built from the class definition.
3515/// For more information, see class TStreamerInfo.
3516
3518{
3519 //build the StreamerInfo if first time for the class
3520 TStreamerInfo *sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetCurrentStreamerInfo();
3521 if (sinfo == nullptr) {
3522 //Have to be sure between the check and the taking of the lock if the current streamer has changed
3524 sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetCurrentStreamerInfo();
3525 if (sinfo == nullptr)
3526 sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetStreamerInfo();
3527 if (sinfo == nullptr) {
3528 const_cast<TClass*>(cl)->BuildRealData(pointer);
3529 sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
3530 const_cast<TClass*>(cl)->SetCurrentStreamerInfo(sinfo);
3531 const_cast<TClass*>(cl)->RegisterStreamerInfo(sinfo);
3532 if (gDebug > 0) Info("WritedClassBuffer", "Creating StreamerInfo for class: %s, version: %d",cl->GetName(),cl->GetClassVersion());
3533 sinfo->Build();
3534 }
3535 } else if (!sinfo->IsCompiled()) {
3537 // Redo the test in case we have been victim of a data race on fIsCompiled.
3538 if (!sinfo->IsCompiled()) {
3539 const_cast<TClass*>(cl)->BuildRealData(pointer);
3540 sinfo->BuildOld();
3541 }
3542 }
3543
3544 //write the class version number and reserve space for the byte count
3545 UInt_t R__c = WriteVersion(cl, kTRUE);
3546
3547 //NOTE: In the future Philippe wants this to happen via a custom action
3548 TagStreamerInfo(sinfo);
3549 ApplySequence(*(sinfo->GetWriteObjectWiseActions()), (char*)pointer);
3550
3551 //write the byte count at the start of the buffer
3552 SetByteCount(R__c, kTRUE);
3553
3554 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));
3555 return 0;
3556}
3557
3558////////////////////////////////////////////////////////////////////////////////
3559/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3560/// The collection needs to be a split TClonesArray or a split vector of pointers.
3561
3563{
3564 if (gDebug) {
3565 //loop on all active members
3566 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3567 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3568 iter != end;
3569 ++iter) {
3570 (*iter).PrintDebug(*this,obj);
3571 (*iter)(*this,obj);
3572 }
3573
3574 } else {
3575 //loop on all active members
3576 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3577 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3578 iter != end;
3579 ++iter) {
3580 (*iter)(*this,obj);
3581 }
3582 }
3583
3584 return 0;
3585}
3586
3587////////////////////////////////////////////////////////////////////////////////
3588/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3589/// The collection needs to be a split TClonesArray or a split vector of pointers.
3590
3591Int_t TBufferFile::ApplySequenceVecPtr(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
3592{
3593 if (gDebug) {
3594 //loop on all active members
3595 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3596 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3597 iter != end;
3598 ++iter) {
3599 if (!start_collection || start_collection == end_collection)
3600 (*iter).PrintDebug(*this, nullptr); // Warning: This limits us to TClonesArray and vector of pointers.
3601 else
3602 (*iter).PrintDebug(*this, *(char**)start_collection); // Warning: This limits us to TClonesArray and vector of pointers.
3603 (*iter)(*this, start_collection, end_collection);
3604 }
3605
3606 } else {
3607 //loop on all active members
3608 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3609 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3610 iter != end;
3611 ++iter) {
3612 (*iter)(*this,start_collection,end_collection);
3613 }
3614 }
3615
3616 return 0;
3617}
3618
3619////////////////////////////////////////////////////////////////////////////////
3620/// Read one collection of objects from the buffer using the StreamerInfoLoopAction.
3621
3622Int_t TBufferFile::ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
3623{
3625 if (gDebug) {
3626
3627 // Get the address of the first item for the PrintDebug.
3628 // (Performance is not essential here since we are going to print to
3629 // the screen anyway).
3630 void *arr0 = start_collection ? loopconfig->GetFirstAddress(start_collection,end_collection) : 0;
3631 // loop on all active members
3632 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3633 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3634 iter != end;
3635 ++iter) {
3636 (*iter).PrintDebug(*this,arr0);
3637 (*iter)(*this,start_collection,end_collection,loopconfig);
3638 }
3639
3640 } else {
3641 //loop on all active members
3642 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
3643 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
3644 iter != end;
3645 ++iter) {
3646 (*iter)(*this,start_collection,end_collection,loopconfig);
3647 }
3648 }
3649
3650 return 0;
3651}
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
bool Bool_t
Definition RtypesCore.h:63
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
constexpr Int_t kMaxInt
Definition RtypesCore.h:112
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
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
float Float_t
Definition RtypesCore.h:57
short Short_t
Definition RtypesCore.h:39
constexpr Bool_t kFALSE
Definition RtypesCore.h:101
double Double_t
Definition RtypesCore.h:59
long long Long64_t
Definition RtypesCore.h:80
constexpr Bool_t kTRUE
Definition RtypesCore.h:100
unsigned long ULong_t
Definition RtypesCore.h:55
#define ClassImp(name)
Definition Rtypes.h:377
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:117
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
char name[80]
Definition TGX11.cxx:110
float xmin
float xmax
R__EXTERN TVirtualMutex * gInterpreterMutex
Int_t gDebug
Definition TROOT.cxx:585
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(...
void Streamer(TBuffer &) override
Stream an object of class TObject.
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.
@ kStreamedMemberWise
Definition TBufferFile.h:69
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:81
UInt_t GetCheckSum(ECheckSum code=kCurrentCheckSum) const
Call GetCheckSum with validity check.
Definition TClass.cxx:6505
void Streamer(void *obj, TBuffer &b, const TClass *onfile_class=nullptr) const
Definition TClass.h:603
EState GetState() const
Definition TClass.h:486
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:4978
static TClass * Load(TBuffer &b)
Load class description from I/O buffer and return class object.
Definition TClass.cxx:5715
TVirtualStreamerInfo * GetCurrentStreamerInfo()
Definition TClass.h:437
void SetLastReadInfo(TVirtualStreamerInfo *info)
Definition TClass.h:443
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:6494
TVirtualStreamerInfo * GetLastReadInfo() const
Definition TClass.h:442
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5704
const ROOT::Detail::TSchemaRuleSet * GetSchemaRules() const
Return the set of the schema rules if any.
Definition TClass.cxx:1932
void Store(TBuffer &b) const
Store class description on I/O buffer.
Definition TClass.cxx:5860
const TObjArray * GetStreamerInfos() const
Definition TClass.h:490
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:5912
Bool_t IsForeign() const
Return kTRUE is the class is Foreign (the class does not have a Streamer method).
Definition TClass.cxx:5947
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0, Bool_t isTransient=kFALSE) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Definition TClass.cxx:4599
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
Definition TClass.cxx:4874
Int_t GetBaseClassOffset(const TClass *toBase, void *address=nullptr, bool isDerivedObject=true)
Definition TClass.cxx:2791
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6086
Bool_t HasDefaultConstructor(Bool_t testio=kFALSE) const
Return true if we have access to a constructor usable for I/O.
Definition TClass.cxx:7393
TVirtualStreamerInfo * GetConversionStreamerInfo(const char *onfile_classname, Int_t version) const
Return a Conversion StreamerInfo from the class 'classname' for version number 'version' to this clas...
Definition TClass.cxx:7086
@ kEmulated
Definition TClass.h:126
TVirtualStreamerInfo * FindStreamerInfo(TObjArray *arr, UInt_t checksum) const
Find the TVirtualStreamerInfo in the StreamerInfos corresponding to checksum.
Definition TClass.cxx:7066
Version_t GetClassVersion() const
Definition TClass.h:418
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:2968
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:217
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:88
Long64_t GetValue(ULong64_t hash, Long64_t key)
Return the value belonging to specified key and hash value.
Definition TExMap.cxx:174
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:117
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:51
A doubly linked list.
Definition TList.h:38
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:578
virtual void SetOnFileClass(const TClass *cl)
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
An array of TObjects.
Definition TObjArray.h:31
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:84
Int_t GetLast() const override
Return index of last object in array.
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:439
virtual void Streamer(TBuffer &)
Stream an object of class TObject.
Definition TObject.cxx:882
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:956
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:970
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:944
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.
Int_t GetClassVersion() const override
void BuildEmulated(TFile *file) override
Create an Emulation TStreamerInfo object.
void Build(Bool_t isTransient=kFALSE) override
Build the I/O data structure for the current class version.
void BuildOld() override
rebuild the TStreamerInfo structure
TStreamerInfoActions::TActionSequence * GetReadObjectWiseActions()
void SetClassVersion(Int_t vers) override
void Clear(Option_t *="") override
If opt contains 'built', reset this StreamerInfo as if Build or BuildOld was never called on it (usef...
UInt_t GetCheckSum() const override
TStreamerInfoActions::TActionSequence * GetWriteObjectWiseActions()
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:421
void UnLink() const
Definition TString.h:265
void SetSize(Ssiz_t s)
Definition TString.h:250
void Zero()
Definition TString.h:266
char * GetPointer()
Definition TString.h:258
void Clobber(Ssiz_t nc)
Clear string and make sure it has a capacity of nc.
Definition TString.cxx:1229
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)
Returns the smallest of a and b.
Definition TMathBase.h:198
Definition file.py:1
TLine l
Definition textangle.C:4