00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <string.h>
00022 #include <typeinfo>
00023
00024 #include "TFile.h"
00025 #include "TBufferFile.h"
00026 #include "TExMap.h"
00027 #include "TClass.h"
00028 #include "TProcessID.h"
00029 #include "TRefTable.h"
00030 #include "TStorage.h"
00031 #include "TError.h"
00032 #include "TClonesArray.h"
00033 #include "TStreamer.h"
00034 #include "TStreamerInfo.h"
00035 #include "TStreamerElement.h"
00036 #include "TSchemaRuleSet.h"
00037 #include "TStreamerInfoActions.h"
00038 #include "TArrayC.h"
00039
00040 #if (defined(__linux) || defined(__APPLE__)) && defined(__i386__) && \
00041 defined(__GNUC__)
00042 #define USE_BSWAPCPY
00043 #endif
00044
00045 #ifdef USE_BSWAPCPY
00046 #include "Bswapcpy.h"
00047 #endif
00048
00049
00050 const UInt_t kNullTag = 0;
00051 const UInt_t kNewClassTag = 0xFFFFFFFF;
00052 const UInt_t kClassMask = 0x80000000;
00053 const UInt_t kByteCountMask = 0x40000000;
00054 const UInt_t kMaxMapCount = 0x3FFFFFFE;
00055 const Version_t kByteCountVMask = 0x4000;
00056 const Version_t kMaxVersion = 0x3FFF;
00057 const Int_t kMapOffset = 2;
00058
00059 Int_t TBufferFile::fgMapSize = kMapSize;
00060
00061
00062 ClassImp(TBufferFile)
00063
00064
00065 static inline ULong_t Void_Hash(const void *ptr)
00066 {
00067
00068
00069 return TString::Hash(&ptr, sizeof(void*));
00070 }
00071
00072
00073 TBufferFile::TBufferFile(TBuffer::EMode mode)
00074 :TBuffer(mode),
00075 fDisplacement(0),fPidOffset(0), fMap(0), fClassMap(0),
00076 fInfo(0), fInfoStack()
00077 {
00078
00079
00080
00081
00082 fMapCount = 0;
00083 fMapSize = fgMapSize;
00084 fMap = 0;
00085 fClassMap = 0;
00086 fParent = 0;
00087 fDisplacement = 0;
00088 }
00089
00090
00091 TBufferFile::TBufferFile(TBuffer::EMode mode, Int_t bufsiz)
00092 :TBuffer(mode,bufsiz),
00093 fDisplacement(0),fPidOffset(0), fMap(0), fClassMap(0),
00094 fInfo(0), fInfoStack()
00095 {
00096
00097
00098
00099 fMapCount = 0;
00100 fMapSize = fgMapSize;
00101 fMap = 0;
00102 fClassMap = 0;
00103 fDisplacement = 0;
00104 }
00105
00106
00107 TBufferFile::TBufferFile(TBuffer::EMode mode, Int_t bufsiz, void *buf, Bool_t adopt, ReAllocCharFun_t reallocfunc) :
00108 TBuffer(mode,bufsiz,buf,adopt,reallocfunc),
00109 fDisplacement(0),fPidOffset(0), fMap(0), fClassMap(0),
00110 fInfo(0), fInfoStack()
00111 {
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 fMapCount = 0;
00122 fMapSize = fgMapSize;
00123 fMap = 0;
00124 fClassMap = 0;
00125 fDisplacement = 0;
00126 }
00127
00128
00129 TBufferFile::~TBufferFile()
00130 {
00131
00132
00133 delete fMap;
00134 delete fClassMap;
00135 }
00136
00137
00138 Int_t TBufferFile::GetVersionOwner() const
00139 {
00140
00141
00142 TFile *file = (TFile*)GetParent();
00143 if (file) return file->GetVersion();
00144 else return 0;
00145 }
00146
00147
00148 void TBufferFile::TagStreamerInfo(TVirtualStreamerInfo* info)
00149 {
00150
00151
00152 TFile *file = (TFile*)GetParent();
00153 if (file) {
00154 TArrayC *cindex = file->GetClassIndex();
00155 Int_t nindex = cindex->GetSize();
00156 Int_t number = info->GetNumber();
00157 if (number < 0 || number >= nindex) {
00158 Error("TagStreamerInfo","StreamerInfo: %s number: %d out of range[0,%d] in file: %s",
00159 info->GetName(),number,nindex,file->GetName());
00160 return;
00161 }
00162 if (cindex->fArray[number] == 0) {
00163 cindex->fArray[0] = 1;
00164 cindex->fArray[number] = 1;
00165 }
00166 }
00167 }
00168
00169
00170 void TBufferFile::IncrementLevel(TVirtualStreamerInfo* info)
00171 {
00172
00173
00174 fInfoStack.push_back(fInfo);
00175 fInfo = (TStreamerInfo*)info;
00176 }
00177
00178
00179 void TBufferFile::DecrementLevel(TVirtualStreamerInfo* )
00180 {
00181
00182
00183 fInfo = fInfoStack.back();
00184 fInfoStack.pop_back();
00185 }
00186
00187
00188 static void frombufOld(char *&buf, Long_t *x)
00189 {
00190
00191
00192
00193
00194
00195
00196 #ifdef R__BYTESWAP
00197 #ifdef R__B64
00198 char *sw = (char *)x;
00199 sw[0] = buf[7];
00200 sw[1] = buf[6];
00201 sw[2] = buf[5];
00202 sw[3] = buf[4];
00203 sw[4] = buf[3];
00204 sw[5] = buf[2];
00205 sw[6] = buf[1];
00206 sw[7] = buf[0];
00207 #else
00208 char *sw = (char *)x;
00209 sw[0] = buf[3];
00210 sw[1] = buf[2];
00211 sw[2] = buf[1];
00212 sw[3] = buf[0];
00213 #endif
00214 #else
00215 memcpy(x, buf, sizeof(Long_t));
00216 #endif
00217 buf += sizeof(Long_t);
00218 }
00219
00220
00221 void TBufferFile::ReadLong(Long_t &l)
00222 {
00223
00224
00225 TFile *file = (TFile*)fParent;
00226 if (file && file->GetVersion() < 30006) {
00227 frombufOld(fBufCur, &l);
00228 } else {
00229 frombuf(fBufCur, &l);
00230 }
00231 }
00232
00233
00234 void TBufferFile::ReadTString(TString &s)
00235 {
00236
00237
00238 s.Streamer(*this);
00239 }
00240
00241
00242 void TBufferFile::WriteTString(const TString &s)
00243 {
00244
00245
00246 ((TString&)s).Streamer(*this);
00247 }
00248
00249
00250 void TBufferFile::SetByteCount(UInt_t cntpos, Bool_t packInVersion)
00251 {
00252
00253
00254
00255 UInt_t cnt = UInt_t(fBufCur - fBuffer) - cntpos - sizeof(UInt_t);
00256 char *buf = (char *)(fBuffer + cntpos);
00257
00258
00259
00260 if (packInVersion) {
00261 union {
00262 UInt_t cnt;
00263 Version_t vers[2];
00264 } v;
00265 v.cnt = cnt;
00266 #ifdef R__BYTESWAP
00267 tobuf(buf, Version_t(v.vers[1] | kByteCountVMask));
00268 tobuf(buf, v.vers[0]);
00269 #else
00270 tobuf(buf, Version_t(v.vers[0] | kByteCountVMask));
00271 tobuf(buf, v.vers[1]);
00272 #endif
00273 } else
00274 tobuf(buf, cnt | kByteCountMask);
00275
00276 if (cnt >= kMaxMapCount) {
00277 Error("WriteByteCount", "bytecount too large (more than %d)", kMaxMapCount);
00278
00279 }
00280 }
00281
00282
00283 Int_t TBufferFile::CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss, const char *classname)
00284 {
00285
00286
00287
00288
00289
00290
00291
00292 if (!bcnt) return 0;
00293
00294 Int_t offset = 0;
00295
00296 Long_t endpos = Long_t(fBuffer) + startpos + bcnt + sizeof(UInt_t);
00297
00298 if (Long_t(fBufCur) != endpos) {
00299 offset = Int_t(Long_t(fBufCur) - endpos);
00300
00301 const char *name = clss ? clss->GetName() : classname ? classname : 0;
00302
00303 if (name) {
00304 if (offset < 0) {
00305 Error("CheckByteCount", "object of class %s read too few bytes: %d instead of %d",
00306 name,bcnt+offset,bcnt);
00307 }
00308 if (offset > 0) {
00309 Error("CheckByteCount", "object of class %s read too many bytes: %d instead of %d",
00310 name,bcnt+offset,bcnt);
00311 if (fParent)
00312 Warning("CheckByteCount","%s::Streamer() not in sync with data on file %s, fix Streamer()",
00313 name, fParent->GetName());
00314 else
00315 Warning("CheckByteCount","%s::Streamer() not in sync with data, fix Streamer()",
00316 name);
00317 }
00318 }
00319 if ( ((char *)endpos) > fBufMax ) {
00320 offset = fBufMax-fBufCur;
00321 Error("CheckByteCount",
00322 "Byte count probably corrupted around buffer position %d:\n\t%d for a possible maximum of %d",
00323 startpos, bcnt, offset);
00324 fBufCur = fBufMax;
00325
00326 } else {
00327
00328 fBufCur = (char *) endpos;
00329
00330 }
00331 }
00332 return offset;
00333 }
00334
00335
00336 Int_t TBufferFile::CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)
00337 {
00338
00339
00340
00341
00342
00343
00344
00345 if (!bcnt) return 0;
00346 return CheckByteCount( startpos, bcnt, clss, 0);
00347 }
00348
00349
00350 Int_t TBufferFile::CheckByteCount(UInt_t startpos, UInt_t bcnt, const char *classname)
00351 {
00352
00353
00354
00355
00356
00357
00358
00359 if (!bcnt) return 0;
00360 return CheckByteCount( startpos, bcnt, 0, classname);
00361 }
00362
00363
00364 void TBufferFile::ReadFloat16(Float_t *f, TStreamerElement *ele)
00365 {
00366
00367
00368
00369 if (ele && ele->GetFactor() != 0) {
00370 ReadWithFactor(f, ele->GetFactor(), ele->GetXmin());
00371 } else {
00372 Int_t nbits = 0;
00373 if (ele) nbits = (Int_t)ele->GetXmin();
00374 if (!nbits) nbits = 12;
00375 ReadWithNbits(f, nbits);
00376 }
00377 }
00378
00379
00380 void TBufferFile::ReadDouble32(Double_t *d, TStreamerElement *ele)
00381 {
00382
00383
00384
00385 if (ele && ele->GetFactor() != 0) {
00386 ReadWithFactor(d, ele->GetFactor(), ele->GetXmin());
00387 } else {
00388 Int_t nbits = 0;
00389 if (ele) nbits = (Int_t)ele->GetXmin();
00390 if (!nbits) {
00391
00392 Float_t afloat;
00393 *this >> afloat;
00394 d[0] = (Double_t)afloat;
00395 } else {
00396 ReadWithNbits(d, nbits);
00397 }
00398 }
00399 }
00400
00401
00402 void TBufferFile::ReadWithFactor(Float_t *ptr, Double_t factor, Double_t minvalue)
00403 {
00404
00405
00406
00407
00408 UInt_t aint;
00409 frombuf(this->fBufCur,&aint);
00410 ptr[0] = (Float_t)(aint/factor + minvalue);
00411 }
00412
00413
00414 void TBufferFile::ReadWithNbits(Float_t *ptr, Int_t nbits)
00415 {
00416
00417
00418
00419
00420
00421 union {
00422 Float_t xx;
00423 Int_t ix;
00424 } temp;
00425 UChar_t theExp;
00426 UShort_t theMan;
00427 frombuf(this->fBufCur,&theExp);
00428 frombuf(this->fBufCur,&theMan);
00429 temp.ix = theExp;
00430 temp.ix <<= 23;
00431 temp.ix |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
00432 if(1<<(nbits+1) & theMan) temp.xx = -temp.xx;
00433 ptr[0] = temp.xx;
00434 }
00435
00436
00437 void TBufferFile::ReadWithFactor(Double_t *ptr, Double_t factor, Double_t minvalue)
00438 {
00439
00440
00441
00442
00443 UInt_t aint;
00444 frombuf(this->fBufCur,&aint);
00445 ptr[0] = (Double_t)(aint/factor + minvalue);
00446 }
00447
00448
00449 void TBufferFile::ReadWithNbits(Double_t *ptr, Int_t nbits)
00450 {
00451
00452
00453
00454
00455
00456 union {
00457 Float_t xx;
00458 Int_t ix;
00459 } temp;
00460 UChar_t theExp;
00461 UShort_t theMan;
00462 frombuf(this->fBufCur,&theExp);
00463 frombuf(this->fBufCur,&theMan);
00464 temp.ix = theExp;
00465 temp.ix <<= 23;
00466 temp.ix |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
00467 if(1<<(nbits+1) & theMan) temp.xx = -temp.xx;
00468 ptr[0] = (Double_t)temp.xx;
00469 }
00470
00471
00472 void TBufferFile::WriteFloat16(Float_t *f, TStreamerElement *ele)
00473 {
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 if (ele && ele->GetFactor() != 0) {
00531
00532
00533
00534 Double_t x = f[0];
00535 Double_t xmin = ele->GetXmin();
00536 Double_t xmax = ele->GetXmax();
00537 if (x < xmin) x = xmin;
00538 if (x > xmax) x = xmax;
00539 UInt_t aint = UInt_t(0.5+ele->GetFactor()*(x-xmin)); *this << aint;
00540 } else {
00541 Int_t nbits = 0;
00542
00543 if (ele) nbits = (Int_t)ele->GetXmin();
00544 if (!nbits) nbits = 12;
00545
00546
00547
00548 union {
00549 Float_t xx;
00550 Int_t ix;
00551 };
00552 xx = f[0];
00553 UChar_t theExp = (UChar_t)(0x000000ff & ((ix<<1)>>24));
00554 UShort_t theMan = ((1<<(nbits+1))-1) & (ix>>(23-nbits-1));
00555 theMan++;
00556 theMan = theMan>>1;
00557 if (theMan&1<<nbits) theMan = (1<<nbits) - 1;
00558 if (xx < 0) theMan |= 1<<(nbits+1);
00559 *this << theExp;
00560 *this << theMan;
00561 }
00562 }
00563
00564
00565 void TBufferFile::WriteDouble32(Double_t *d, TStreamerElement *ele)
00566 {
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 if (ele && ele->GetFactor() != 0) {
00624
00625
00626
00627 Double_t x = d[0];
00628 Double_t xmin = ele->GetXmin();
00629 Double_t xmax = ele->GetXmax();
00630 if (x < xmin) x = xmin;
00631 if (x > xmax) x = xmax;
00632 UInt_t aint = UInt_t(0.5+ele->GetFactor()*(x-xmin)); *this << aint;
00633 } else {
00634 Int_t nbits = 0;
00635
00636 if (ele) nbits = (Int_t)ele->GetXmin();
00637 if (!nbits) {
00638
00639 Float_t afloat = (Float_t)d[0];
00640 *this << afloat;
00641 } else {
00642
00643
00644
00645 union {
00646 Float_t xx;
00647 Int_t ix;
00648 };
00649 xx = (Float_t)d[0];
00650 UChar_t theExp = (UChar_t)(0x000000ff & ((ix<<1)>>24));
00651 UShort_t theMan = ((1<<(nbits+1))-1) & (ix>>(23-nbits-1)) ;
00652 theMan++;
00653 theMan = theMan>>1;
00654 if (theMan&1<<nbits) theMan = (1<<nbits)-1 ;
00655 if (xx < 0) theMan |= 1<<(nbits+1);
00656 *this << theExp;
00657 *this << theMan;
00658 }
00659 }
00660 }
00661
00662
00663 Int_t TBufferFile::ReadArray(Bool_t *&b)
00664 {
00665
00666
00667
00668
00669 R__ASSERT(IsReading());
00670
00671 Int_t n;
00672 *this >> n;
00673
00674 if (n <= 0 || n > fBufSize) return 0;
00675
00676 if (!b) b = new Bool_t[n];
00677
00678 if (sizeof(Bool_t) > 1) {
00679 for (int i = 0; i < n; i++)
00680 frombuf(fBufCur, &b[i]);
00681 } else {
00682 Int_t l = sizeof(Bool_t)*n;
00683 memcpy(b, fBufCur, l);
00684 fBufCur += l;
00685 }
00686
00687 return n;
00688 }
00689
00690
00691 Int_t TBufferFile::ReadArray(Char_t *&c)
00692 {
00693
00694
00695
00696
00697 R__ASSERT(IsReading());
00698
00699 Int_t n;
00700 *this >> n;
00701 Int_t l = sizeof(Char_t)*n;
00702
00703 if (l <= 0 || l > fBufSize) return 0;
00704
00705 if (!c) c = new Char_t[n];
00706
00707 memcpy(c, fBufCur, l);
00708 fBufCur += l;
00709
00710 return n;
00711 }
00712
00713
00714 Int_t TBufferFile::ReadArray(Short_t *&h)
00715 {
00716
00717
00718
00719
00720 R__ASSERT(IsReading());
00721
00722 Int_t n;
00723 *this >> n;
00724 Int_t l = sizeof(Short_t)*n;
00725
00726 if (l <= 0 || l > fBufSize) return 0;
00727
00728 if (!h) h = new Short_t[n];
00729
00730 #ifdef R__BYTESWAP
00731 # ifdef USE_BSWAPCPY
00732 bswapcpy16(h, fBufCur, n);
00733 fBufCur += l;
00734 # else
00735 for (int i = 0; i < n; i++)
00736 frombuf(fBufCur, &h[i]);
00737 # endif
00738 #else
00739 memcpy(h, fBufCur, l);
00740 fBufCur += l;
00741 #endif
00742
00743 return n;
00744 }
00745
00746
00747 Int_t TBufferFile::ReadArray(Int_t *&ii)
00748 {
00749
00750
00751
00752
00753 R__ASSERT(IsReading());
00754
00755 Int_t n;
00756 *this >> n;
00757 Int_t l = sizeof(Int_t)*n;
00758
00759 if (l <= 0 || l > fBufSize) return 0;
00760
00761 if (!ii) ii = new Int_t[n];
00762
00763 #ifdef R__BYTESWAP
00764 # ifdef USE_BSWAPCPY
00765 bswapcpy32(ii, fBufCur, n);
00766 fBufCur += l;
00767 # else
00768 for (int i = 0; i < n; i++)
00769 frombuf(fBufCur, &ii[i]);
00770 # endif
00771 #else
00772 memcpy(ii, fBufCur, l);
00773 fBufCur += l;
00774 #endif
00775
00776 return n;
00777 }
00778
00779
00780 Int_t TBufferFile::ReadArray(Long_t *&ll)
00781 {
00782
00783
00784
00785
00786 R__ASSERT(IsReading());
00787
00788 Int_t n;
00789 *this >> n;
00790 Int_t l = sizeof(Long_t)*n;
00791
00792 if (l <= 0 || l > fBufSize) return 0;
00793
00794 if (!ll) ll = new Long_t[n];
00795
00796 TFile *file = (TFile*)fParent;
00797 if (file && file->GetVersion() < 30006) {
00798 for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
00799 } else {
00800 for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
00801 }
00802 return n;
00803 }
00804
00805
00806 Int_t TBufferFile::ReadArray(Long64_t *&ll)
00807 {
00808
00809
00810
00811
00812 R__ASSERT(IsReading());
00813
00814 Int_t n;
00815 *this >> n;
00816 Int_t l = sizeof(Long64_t)*n;
00817
00818 if (l <= 0 || l > fBufSize) return 0;
00819
00820 if (!ll) ll = new Long64_t[n];
00821
00822 #ifdef R__BYTESWAP
00823 for (int i = 0; i < n; i++)
00824 frombuf(fBufCur, &ll[i]);
00825 #else
00826 memcpy(ll, fBufCur, l);
00827 fBufCur += l;
00828 #endif
00829
00830 return n;
00831 }
00832
00833
00834 Int_t TBufferFile::ReadArray(Float_t *&f)
00835 {
00836
00837
00838
00839
00840 R__ASSERT(IsReading());
00841
00842 Int_t n;
00843 *this >> n;
00844 Int_t l = sizeof(Float_t)*n;
00845
00846 if (l <= 0 || l > fBufSize) return 0;
00847
00848 if (!f) f = new Float_t[n];
00849
00850 #ifdef R__BYTESWAP
00851 # ifdef USE_BSWAPCPY
00852 bswapcpy32(f, fBufCur, n);
00853 fBufCur += l;
00854 # else
00855 for (int i = 0; i < n; i++)
00856 frombuf(fBufCur, &f[i]);
00857 # endif
00858 #else
00859 memcpy(f, fBufCur, l);
00860 fBufCur += l;
00861 #endif
00862
00863 return n;
00864 }
00865
00866
00867 Int_t TBufferFile::ReadArray(Double_t *&d)
00868 {
00869
00870
00871
00872
00873 R__ASSERT(IsReading());
00874
00875 Int_t n;
00876 *this >> n;
00877 Int_t l = sizeof(Double_t)*n;
00878
00879 if (l <= 0 || l > fBufSize) return 0;
00880
00881 if (!d) d = new Double_t[n];
00882
00883 #ifdef R__BYTESWAP
00884 for (int i = 0; i < n; i++)
00885 frombuf(fBufCur, &d[i]);
00886 #else
00887 memcpy(d, fBufCur, l);
00888 fBufCur += l;
00889 #endif
00890
00891 return n;
00892 }
00893
00894
00895 Int_t TBufferFile::ReadArrayFloat16(Float_t *&f, TStreamerElement *ele)
00896 {
00897
00898
00899
00900
00901
00902 R__ASSERT(IsReading());
00903
00904 Int_t n;
00905 *this >> n;
00906
00907 if (n <= 0 || 3*n > fBufSize) return 0;
00908
00909 if (!f) f = new Float_t[n];
00910
00911 ReadFastArrayFloat16(f,n,ele);
00912
00913 return n;
00914 }
00915
00916
00917 Int_t TBufferFile::ReadArrayDouble32(Double_t *&d, TStreamerElement *ele)
00918 {
00919
00920
00921
00922
00923
00924 R__ASSERT(IsReading());
00925
00926 Int_t n;
00927 *this >> n;
00928
00929 if (n <= 0 || 3*n > fBufSize) return 0;
00930
00931 if (!d) d = new Double_t[n];
00932
00933 ReadFastArrayDouble32(d,n,ele);
00934
00935 return n;
00936 }
00937
00938
00939 Int_t TBufferFile::ReadStaticArray(Bool_t *b)
00940 {
00941
00942
00943
00944 R__ASSERT(IsReading());
00945
00946 Int_t n;
00947 *this >> n;
00948
00949 if (n <= 0 || n > fBufSize) return 0;
00950
00951 if (!b) return 0;
00952
00953 if (sizeof(Bool_t) > 1) {
00954 for (int i = 0; i < n; i++)
00955 frombuf(fBufCur, &b[i]);
00956 } else {
00957 Int_t l = sizeof(Bool_t)*n;
00958 memcpy(b, fBufCur, l);
00959 fBufCur += l;
00960 }
00961
00962 return n;
00963 }
00964
00965
00966 Int_t TBufferFile::ReadStaticArray(Char_t *c)
00967 {
00968
00969
00970
00971 R__ASSERT(IsReading());
00972
00973 Int_t n;
00974 *this >> n;
00975 Int_t l = sizeof(Char_t)*n;
00976
00977 if (l <= 0 || l > fBufSize) return 0;
00978
00979 if (!c) return 0;
00980
00981 memcpy(c, fBufCur, l);
00982 fBufCur += l;
00983
00984 return n;
00985 }
00986
00987
00988 Int_t TBufferFile::ReadStaticArray(Short_t *h)
00989 {
00990
00991
00992
00993 R__ASSERT(IsReading());
00994
00995 Int_t n;
00996 *this >> n;
00997 Int_t l = sizeof(Short_t)*n;
00998
00999 if (l <= 0 || l > fBufSize) return 0;
01000
01001 if (!h) return 0;
01002
01003 #ifdef R__BYTESWAP
01004 # ifdef USE_BSWAPCPY
01005 bswapcpy16(h, fBufCur, n);
01006 fBufCur += l;
01007 # else
01008 for (int i = 0; i < n; i++)
01009 frombuf(fBufCur, &h[i]);
01010 # endif
01011 #else
01012 memcpy(h, fBufCur, l);
01013 fBufCur += l;
01014 #endif
01015
01016 return n;
01017 }
01018
01019
01020 Int_t TBufferFile::ReadStaticArray(Int_t *ii)
01021 {
01022
01023
01024
01025 R__ASSERT(IsReading());
01026
01027 Int_t n;
01028 *this >> n;
01029 Int_t l = sizeof(Int_t)*n;
01030
01031 if (l <= 0 || l > fBufSize) return 0;
01032
01033 if (!ii) return 0;
01034
01035 #ifdef R__BYTESWAP
01036 # ifdef USE_BSWAPCPY
01037 bswapcpy32(ii, fBufCur, n);
01038 fBufCur += sizeof(Int_t)*n;
01039 # else
01040 for (int i = 0; i < n; i++)
01041 frombuf(fBufCur, &ii[i]);
01042 # endif
01043 #else
01044 memcpy(ii, fBufCur, l);
01045 fBufCur += l;
01046 #endif
01047
01048 return n;
01049 }
01050
01051
01052 Int_t TBufferFile::ReadStaticArray(Long_t *ll)
01053 {
01054
01055
01056
01057 R__ASSERT(IsReading());
01058
01059 Int_t n;
01060 *this >> n;
01061 Int_t l = sizeof(Long_t)*n;
01062
01063 if (l <= 0 || l > fBufSize) return 0;
01064
01065 if (!ll) return 0;
01066
01067 TFile *file = (TFile*)fParent;
01068 if (file && file->GetVersion() < 30006) {
01069 for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
01070 } else {
01071 for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
01072 }
01073 return n;
01074 }
01075
01076
01077 Int_t TBufferFile::ReadStaticArray(Long64_t *ll)
01078 {
01079
01080
01081
01082 R__ASSERT(IsReading());
01083
01084 Int_t n;
01085 *this >> n;
01086 Int_t l = sizeof(Long64_t)*n;
01087
01088 if (l <= 0 || l > fBufSize) return 0;
01089
01090 if (!ll) return 0;
01091
01092 #ifdef R__BYTESWAP
01093 for (int i = 0; i < n; i++)
01094 frombuf(fBufCur, &ll[i]);
01095 #else
01096 memcpy(ll, fBufCur, l);
01097 fBufCur += l;
01098 #endif
01099
01100 return n;
01101 }
01102
01103
01104 Int_t TBufferFile::ReadStaticArray(Float_t *f)
01105 {
01106
01107
01108
01109 R__ASSERT(IsReading());
01110
01111 Int_t n;
01112 *this >> n;
01113 Int_t l = sizeof(Float_t)*n;
01114
01115 if (n <= 0 || l > fBufSize) return 0;
01116
01117 if (!f) return 0;
01118
01119 #ifdef R__BYTESWAP
01120 # ifdef USE_BSWAPCPY
01121 bswapcpy32(f, fBufCur, n);
01122 fBufCur += sizeof(Float_t)*n;
01123 # else
01124 for (int i = 0; i < n; i++)
01125 frombuf(fBufCur, &f[i]);
01126 # endif
01127 #else
01128 memcpy(f, fBufCur, l);
01129 fBufCur += l;
01130 #endif
01131
01132 return n;
01133 }
01134
01135
01136 Int_t TBufferFile::ReadStaticArray(Double_t *d)
01137 {
01138
01139
01140
01141 R__ASSERT(IsReading());
01142
01143 Int_t n;
01144 *this >> n;
01145 Int_t l = sizeof(Double_t)*n;
01146
01147 if (n <= 0 || l > fBufSize) return 0;
01148
01149 if (!d) return 0;
01150
01151 #ifdef R__BYTESWAP
01152 for (int i = 0; i < n; i++)
01153 frombuf(fBufCur, &d[i]);
01154 #else
01155 memcpy(d, fBufCur, l);
01156 fBufCur += l;
01157 #endif
01158
01159 return n;
01160 }
01161
01162
01163 Int_t TBufferFile::ReadStaticArrayFloat16(Float_t *f, TStreamerElement *ele)
01164 {
01165
01166
01167
01168
01169 R__ASSERT(IsReading());
01170
01171 Int_t n;
01172 *this >> n;
01173
01174 if (n <= 0 || 3*n > fBufSize) return 0;
01175
01176 if (!f) return 0;
01177
01178 ReadFastArrayFloat16(f,n,ele);
01179
01180 return n;
01181 }
01182
01183
01184 Int_t TBufferFile::ReadStaticArrayDouble32(Double_t *d, TStreamerElement *ele)
01185 {
01186
01187
01188
01189
01190 R__ASSERT(IsReading());
01191
01192 Int_t n;
01193 *this >> n;
01194
01195 if (n <= 0 || 3*n > fBufSize) return 0;
01196
01197 if (!d) return 0;
01198
01199 ReadFastArrayDouble32(d,n,ele);
01200
01201 return n;
01202 }
01203
01204
01205 void TBufferFile::ReadFastArray(Bool_t *b, Int_t n)
01206 {
01207
01208
01209 if (n <= 0 || n > fBufSize) return;
01210
01211 if (sizeof(Bool_t) > 1) {
01212 for (int i = 0; i < n; i++)
01213 frombuf(fBufCur, &b[i]);
01214 } else {
01215 Int_t l = sizeof(Bool_t)*n;
01216 memcpy(b, fBufCur, l);
01217 fBufCur += l;
01218 }
01219 }
01220
01221
01222 void TBufferFile::ReadFastArray(Char_t *c, Int_t n)
01223 {
01224
01225
01226 if (n <= 0 || n > fBufSize) return;
01227
01228 Int_t l = sizeof(Char_t)*n;
01229 memcpy(c, fBufCur, l);
01230 fBufCur += l;
01231 }
01232
01233
01234 void TBufferFile::ReadFastArrayString(Char_t *c, Int_t n)
01235 {
01236
01237
01238 Int_t len;
01239 UChar_t lenchar;
01240 *this >> lenchar;
01241 if (lenchar < 255) {
01242 len = lenchar;
01243 } else {
01244 *this >> len;
01245 }
01246 if (len) {
01247 if (len <= 0 || len > fBufSize) return;
01248 Int_t blen = len;
01249 if (len >= n) len = n-1;
01250
01251 Int_t l = sizeof(Char_t)*len;
01252 memcpy(c, fBufCur, l);
01253 fBufCur += blen;
01254
01255 c[len] = 0;
01256 } else {
01257 c[0] = 0;
01258 }
01259 }
01260
01261
01262 void TBufferFile::ReadFastArray(Short_t *h, Int_t n)
01263 {
01264
01265
01266 Int_t l = sizeof(Short_t)*n;
01267 if (n <= 0 || l > fBufSize) return;
01268
01269 #ifdef R__BYTESWAP
01270 # ifdef USE_BSWAPCPY
01271 bswapcpy16(h, fBufCur, n);
01272 fBufCur += sizeof(Short_t)*n;
01273 # else
01274 for (int i = 0; i < n; i++)
01275 frombuf(fBufCur, &h[i]);
01276 # endif
01277 #else
01278 memcpy(h, fBufCur, l);
01279 fBufCur += l;
01280 #endif
01281 }
01282
01283
01284 void TBufferFile::ReadFastArray(Int_t *ii, Int_t n)
01285 {
01286
01287
01288 Int_t l = sizeof(Int_t)*n;
01289 if (l <= 0 || l > fBufSize) return;
01290
01291 #ifdef R__BYTESWAP
01292 # ifdef USE_BSWAPCPY
01293 bswapcpy32(ii, fBufCur, n);
01294 fBufCur += sizeof(Int_t)*n;
01295 # else
01296 for (int i = 0; i < n; i++)
01297 frombuf(fBufCur, &ii[i]);
01298 # endif
01299 #else
01300 memcpy(ii, fBufCur, l);
01301 fBufCur += l;
01302 #endif
01303 }
01304
01305
01306 void TBufferFile::ReadFastArray(Long_t *ll, Int_t n)
01307 {
01308
01309
01310 Int_t l = sizeof(Long_t)*n;
01311 if (l <= 0 || l > fBufSize) return;
01312
01313 TFile *file = (TFile*)fParent;
01314 if (file && file->GetVersion() < 30006) {
01315 for (int i = 0; i < n; i++) frombufOld(fBufCur, &ll[i]);
01316 } else {
01317 for (int i = 0; i < n; i++) frombuf(fBufCur, &ll[i]);
01318 }
01319 }
01320
01321
01322 void TBufferFile::ReadFastArray(Long64_t *ll, Int_t n)
01323 {
01324
01325
01326 Int_t l = sizeof(Long64_t)*n;
01327 if (l <= 0 || l > fBufSize) return;
01328
01329 #ifdef R__BYTESWAP
01330 for (int i = 0; i < n; i++)
01331 frombuf(fBufCur, &ll[i]);
01332 #else
01333 memcpy(ll, fBufCur, l);
01334 fBufCur += l;
01335 #endif
01336 }
01337
01338
01339 void TBufferFile::ReadFastArray(Float_t *f, Int_t n)
01340 {
01341
01342
01343 Int_t l = sizeof(Float_t)*n;
01344 if (l <= 0 || l > fBufSize) return;
01345
01346 #ifdef R__BYTESWAP
01347 # ifdef USE_BSWAPCPY
01348 bswapcpy32(f, fBufCur, n);
01349 fBufCur += sizeof(Float_t)*n;
01350 # else
01351 for (int i = 0; i < n; i++)
01352 frombuf(fBufCur, &f[i]);
01353 # endif
01354 #else
01355 memcpy(f, fBufCur, l);
01356 fBufCur += l;
01357 #endif
01358 }
01359
01360
01361 void TBufferFile::ReadFastArray(Double_t *d, Int_t n)
01362 {
01363
01364
01365 Int_t l = sizeof(Double_t)*n;
01366 if (l <= 0 || l > fBufSize) return;
01367
01368 #ifdef R__BYTESWAP
01369 for (int i = 0; i < n; i++)
01370 frombuf(fBufCur, &d[i]);
01371 #else
01372 memcpy(d, fBufCur, l);
01373 fBufCur += l;
01374 #endif
01375 }
01376
01377
01378 void TBufferFile::ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele)
01379 {
01380
01381
01382
01383 if (n <= 0 || 3*n > fBufSize) return;
01384
01385 if (ele && ele->GetFactor() != 0) {
01386
01387 Double_t xmin = ele->GetXmin();
01388 Double_t factor = ele->GetFactor();
01389 for (int j=0;j < n; j++) {
01390 UInt_t aint; *this >> aint; f[j] = (Float_t)(aint/factor + xmin);
01391 }
01392 } else {
01393 Int_t i;
01394 Int_t nbits = 0;
01395 if (ele) nbits = (Int_t)ele->GetXmin();
01396 if (!nbits) nbits = 12;
01397
01398
01399 union {
01400 Float_t xx;
01401 Int_t ix;
01402 };
01403 UChar_t theExp;
01404 UShort_t theMan;
01405 for (i = 0; i < n; i++) {
01406 *this >> theExp;
01407 *this >> theMan;
01408 ix = theExp;
01409 ix <<= 23;
01410 ix |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
01411 if(1<<(nbits+1) & theMan) xx = -xx;
01412 f[i] = xx;
01413 }
01414 }
01415 }
01416
01417
01418 void TBufferFile::ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele)
01419 {
01420
01421
01422
01423 if (n <= 0 || 3*n > fBufSize) return;
01424
01425 if (ele && ele->GetFactor() != 0) {
01426
01427 Double_t xmin = ele->GetXmin();
01428 Double_t factor = ele->GetFactor();
01429 for (int j=0;j < n; j++) {
01430 UInt_t aint; *this >> aint; d[j] = (Double_t)(aint/factor + xmin);
01431 }
01432 } else {
01433 Int_t i;
01434 Int_t nbits = 0;
01435 if (ele) nbits = (Int_t)ele->GetXmin();
01436 if (!nbits) {
01437
01438 Float_t afloat;
01439 for (i = 0; i < n; i++) {
01440 *this >> afloat;
01441 d[i] = (Double_t)afloat;
01442 }
01443 } else {
01444
01445
01446 union {
01447 Float_t xx;
01448 Int_t ix;
01449 };
01450 UChar_t theExp;
01451 UShort_t theMan;
01452 for (i = 0; i < n; i++) {
01453 *this >> theExp;
01454 *this >> theMan;
01455 ix = theExp;
01456 ix <<= 23;
01457 ix |= (theMan & ((1<<(nbits+1))-1)) <<(23-nbits);
01458 if (1<<(nbits+1) & theMan) xx = -xx;
01459 d[i] = (Double_t)xx;
01460 }
01461 }
01462 }
01463 }
01464
01465
01466 void TBufferFile::ReadFastArray(void *start, const TClass *cl, Int_t n,
01467 TMemberStreamer *streamer, const TClass* onFileClass )
01468 {
01469
01470
01471
01472
01473 if (streamer) {
01474 streamer->SetOnFileClass(onFileClass);
01475 (*streamer)(*this,start,0);
01476 return;
01477 }
01478
01479 int objectSize = cl->Size();
01480 char *obj = (char*)start;
01481 char *end = obj + n*objectSize;
01482
01483 for(; obj<end; obj+=objectSize) ((TClass*)cl)->Streamer(obj,*this, onFileClass);
01484 }
01485
01486
01487 void TBufferFile::ReadFastArray(void **start, const TClass *cl, Int_t n,
01488 Bool_t isPreAlloc, TMemberStreamer *streamer, const TClass* onFileClass)
01489 {
01490
01491
01492
01493
01494
01495
01496
01497
01498 if (streamer) {
01499 if (isPreAlloc) {
01500 for (Int_t j=0;j<n;j++) {
01501 if (!start[j]) start[j] = cl->New();
01502 }
01503 }
01504 streamer->SetOnFileClass(onFileClass);
01505 (*streamer)(*this,(void*)start,0);
01506 return;
01507 }
01508
01509 if (!isPreAlloc) {
01510
01511 for (Int_t j=0; j<n; j++){
01512
01513 void *old = start[j];
01514 start[j] = ReadObjectAny(cl);
01515 if (old && old!=start[j] &&
01516 TStreamerInfo::CanDelete()
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532 ) {
01533 ((TClass*)cl)->Destructor(old,kFALSE);
01534 }
01535 }
01536
01537 } else {
01538
01539 for (Int_t j=0; j<n; j++){
01540 if (!start[j]) start[j] = ((TClass*)cl)->New();
01541 ((TClass*)cl)->Streamer(start[j],*this,onFileClass);
01542 }
01543
01544 }
01545 }
01546
01547
01548 void TBufferFile::WriteArray(const Bool_t *b, Int_t n)
01549 {
01550
01551
01552 R__ASSERT(IsWriting());
01553
01554 *this << n;
01555
01556 if (n <= 0) return;
01557
01558 R__ASSERT(b);
01559
01560 Int_t l = sizeof(UChar_t)*n;
01561 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01562
01563 if (sizeof(Bool_t) > 1) {
01564 for (int i = 0; i < n; i++)
01565 tobuf(fBufCur, b[i]);
01566 } else {
01567 memcpy(fBufCur, b, l);
01568 fBufCur += l;
01569 }
01570 }
01571
01572
01573 void TBufferFile::WriteArray(const Char_t *c, Int_t n)
01574 {
01575
01576
01577 R__ASSERT(IsWriting());
01578
01579 *this << n;
01580
01581 if (n <= 0) return;
01582
01583 R__ASSERT(c);
01584
01585 Int_t l = sizeof(Char_t)*n;
01586 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01587
01588 memcpy(fBufCur, c, l);
01589 fBufCur += l;
01590 }
01591
01592
01593 void TBufferFile::WriteArray(const Short_t *h, Int_t n)
01594 {
01595
01596
01597 R__ASSERT(IsWriting());
01598
01599 *this << n;
01600
01601 if (n <= 0) return;
01602
01603 R__ASSERT(h);
01604
01605 Int_t l = sizeof(Short_t)*n;
01606 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01607
01608 #ifdef R__BYTESWAP
01609 # ifdef USE_BSWAPCPY
01610 bswapcpy16(fBufCur, h, n);
01611 fBufCur += l;
01612 # else
01613 for (int i = 0; i < n; i++)
01614 tobuf(fBufCur, h[i]);
01615 # endif
01616 #else
01617 memcpy(fBufCur, h, l);
01618 fBufCur += l;
01619 #endif
01620 }
01621
01622
01623 void TBufferFile::WriteArray(const Int_t *ii, Int_t n)
01624 {
01625
01626
01627 R__ASSERT(IsWriting());
01628
01629 *this << n;
01630
01631 if (n <= 0) return;
01632
01633 R__ASSERT(ii);
01634
01635 Int_t l = sizeof(Int_t)*n;
01636 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01637
01638 #ifdef R__BYTESWAP
01639 # ifdef USE_BSWAPCPY
01640 bswapcpy32(fBufCur, ii, n);
01641 fBufCur += l;
01642 # else
01643 for (int i = 0; i < n; i++)
01644 tobuf(fBufCur, ii[i]);
01645 # endif
01646 #else
01647 memcpy(fBufCur, ii, l);
01648 fBufCur += l;
01649 #endif
01650 }
01651
01652
01653 void TBufferFile::WriteArray(const Long_t *ll, Int_t n)
01654 {
01655
01656
01657 R__ASSERT(IsWriting());
01658
01659 *this << n;
01660
01661 if (n <= 0) return;
01662
01663 R__ASSERT(ll);
01664
01665 Int_t l = 8*n;
01666 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01667 for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
01668 }
01669
01670
01671 void TBufferFile::WriteArray(const ULong_t *ll, Int_t n)
01672 {
01673
01674
01675
01676
01677 R__ASSERT(IsWriting());
01678
01679 *this << n;
01680
01681 if (n <= 0) return;
01682
01683 R__ASSERT(ll);
01684
01685 Int_t l = 8*n;
01686 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01687 for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
01688 }
01689
01690
01691 void TBufferFile::WriteArray(const Long64_t *ll, Int_t n)
01692 {
01693
01694
01695 R__ASSERT(IsWriting());
01696
01697 *this << n;
01698
01699 if (n <= 0) return;
01700
01701 R__ASSERT(ll);
01702
01703 Int_t l = sizeof(Long64_t)*n;
01704 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01705
01706 #ifdef R__BYTESWAP
01707 for (int i = 0; i < n; i++)
01708 tobuf(fBufCur, ll[i]);
01709 #else
01710 memcpy(fBufCur, ll, l);
01711 fBufCur += l;
01712 #endif
01713 }
01714
01715
01716 void TBufferFile::WriteArray(const Float_t *f, Int_t n)
01717 {
01718
01719
01720 R__ASSERT(IsWriting());
01721
01722 *this << n;
01723
01724 if (n <= 0) return;
01725
01726 R__ASSERT(f);
01727
01728 Int_t l = sizeof(Float_t)*n;
01729 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01730
01731 #ifdef R__BYTESWAP
01732 # ifdef USE_BSWAPCPY
01733 bswapcpy32(fBufCur, f, n);
01734 fBufCur += l;
01735 # else
01736 for (int i = 0; i < n; i++)
01737 tobuf(fBufCur, f[i]);
01738 # endif
01739 #else
01740 memcpy(fBufCur, f, l);
01741 fBufCur += l;
01742 #endif
01743 }
01744
01745
01746 void TBufferFile::WriteArray(const Double_t *d, Int_t n)
01747 {
01748
01749
01750 R__ASSERT(IsWriting());
01751
01752 *this << n;
01753
01754 if (n <= 0) return;
01755
01756 R__ASSERT(d);
01757
01758 Int_t l = sizeof(Double_t)*n;
01759 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01760
01761 #ifdef R__BYTESWAP
01762 for (int i = 0; i < n; i++)
01763 tobuf(fBufCur, d[i]);
01764 #else
01765 memcpy(fBufCur, d, l);
01766 fBufCur += l;
01767 #endif
01768 }
01769
01770
01771 void TBufferFile::WriteArrayFloat16(const Float_t *f, Int_t n, TStreamerElement *ele)
01772 {
01773
01774
01775
01776 R__ASSERT(IsWriting());
01777
01778 *this << n;
01779
01780 if (n <= 0) return;
01781
01782 R__ASSERT(f);
01783
01784 Int_t l = sizeof(Float_t)*n;
01785 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01786
01787 WriteFastArrayFloat16(f,n,ele);
01788 }
01789
01790
01791 void TBufferFile::WriteArrayDouble32(const Double_t *d, Int_t n, TStreamerElement *ele)
01792 {
01793
01794
01795
01796 R__ASSERT(IsWriting());
01797
01798 *this << n;
01799
01800 if (n <= 0) return;
01801
01802 R__ASSERT(d);
01803
01804 Int_t l = sizeof(Float_t)*n;
01805 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01806
01807 WriteFastArrayDouble32(d,n,ele);
01808 }
01809
01810
01811 void TBufferFile::WriteFastArray(const Bool_t *b, Int_t n)
01812 {
01813
01814
01815 if (n <= 0) return;
01816
01817 Int_t l = sizeof(UChar_t)*n;
01818 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01819
01820 if (sizeof(Bool_t) > 1) {
01821 for (int i = 0; i < n; i++)
01822 tobuf(fBufCur, b[i]);
01823 } else {
01824 memcpy(fBufCur, b, l);
01825 fBufCur += l;
01826 }
01827 }
01828
01829
01830 void TBufferFile::WriteFastArray(const Char_t *c, Int_t n)
01831 {
01832
01833
01834 if (n <= 0) return;
01835
01836 Int_t l = sizeof(Char_t)*n;
01837 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01838
01839 memcpy(fBufCur, c, l);
01840 fBufCur += l;
01841 }
01842
01843
01844 void TBufferFile::WriteFastArrayString(const Char_t *c, Int_t n)
01845 {
01846
01847
01848 if (n < 255) {
01849 *this << (UChar_t)n;
01850 } else {
01851 *this << (UChar_t)255;
01852 *this << n;
01853 }
01854
01855 if (n <= 0) return;
01856
01857 Int_t l = sizeof(Char_t)*n;
01858 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01859
01860 memcpy(fBufCur, c, l);
01861 fBufCur += l;
01862 }
01863
01864
01865 void TBufferFile::WriteFastArray(const Short_t *h, Int_t n)
01866 {
01867
01868
01869 if (n <= 0) return;
01870
01871 Int_t l = sizeof(Short_t)*n;
01872 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01873
01874 #ifdef R__BYTESWAP
01875 # ifdef USE_BSWAPCPY
01876 bswapcpy16(fBufCur, h, n);
01877 fBufCur += l;
01878 # else
01879 for (int i = 0; i < n; i++)
01880 tobuf(fBufCur, h[i]);
01881 # endif
01882 #else
01883 memcpy(fBufCur, h, l);
01884 fBufCur += l;
01885 #endif
01886 }
01887
01888
01889 void TBufferFile::WriteFastArray(const Int_t *ii, Int_t n)
01890 {
01891
01892
01893 if (n <= 0) return;
01894
01895 Int_t l = sizeof(Int_t)*n;
01896 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01897
01898 #ifdef R__BYTESWAP
01899 # ifdef USE_BSWAPCPY
01900 bswapcpy32(fBufCur, ii, n);
01901 fBufCur += l;
01902 # else
01903 for (int i = 0; i < n; i++)
01904 tobuf(fBufCur, ii[i]);
01905 # endif
01906 #else
01907 memcpy(fBufCur, ii, l);
01908 fBufCur += l;
01909 #endif
01910 }
01911
01912
01913 void TBufferFile::WriteFastArray(const Long_t *ll, Int_t n)
01914 {
01915
01916
01917 if (n <= 0) return;
01918
01919 Int_t l = 8*n;
01920 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01921
01922 for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
01923 }
01924
01925
01926 void TBufferFile::WriteFastArray(const ULong_t *ll, Int_t n)
01927 {
01928
01929
01930
01931
01932 if (n <= 0) return;
01933
01934 Int_t l = 8*n;
01935 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01936
01937 for (int i = 0; i < n; i++) tobuf(fBufCur, ll[i]);
01938 }
01939
01940
01941 void TBufferFile::WriteFastArray(const Long64_t *ll, Int_t n)
01942 {
01943
01944
01945 if (n <= 0) return;
01946
01947 Int_t l = sizeof(Long64_t)*n;
01948 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01949
01950 #ifdef R__BYTESWAP
01951 for (int i = 0; i < n; i++)
01952 tobuf(fBufCur, ll[i]);
01953 #else
01954 memcpy(fBufCur, ll, l);
01955 fBufCur += l;
01956 #endif
01957 }
01958
01959
01960 void TBufferFile::WriteFastArray(const Float_t *f, Int_t n)
01961 {
01962
01963
01964 if (n <= 0) return;
01965
01966 Int_t l = sizeof(Float_t)*n;
01967 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01968
01969 #ifdef R__BYTESWAP
01970 # ifdef USE_BSWAPCPY
01971 bswapcpy32(fBufCur, f, n);
01972 fBufCur += l;
01973 # else
01974 for (int i = 0; i < n; i++)
01975 tobuf(fBufCur, f[i]);
01976 # endif
01977 #else
01978 memcpy(fBufCur, f, l);
01979 fBufCur += l;
01980 #endif
01981 }
01982
01983
01984 void TBufferFile::WriteFastArray(const Double_t *d, Int_t n)
01985 {
01986
01987
01988 if (n <= 0) return;
01989
01990 Int_t l = sizeof(Double_t)*n;
01991 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
01992
01993 #ifdef R__BYTESWAP
01994 for (int i = 0; i < n; i++)
01995 tobuf(fBufCur, d[i]);
01996 #else
01997 memcpy(fBufCur, d, l);
01998 fBufCur += l;
01999 #endif
02000 }
02001
02002
02003 void TBufferFile::WriteFastArrayFloat16(const Float_t *f, Int_t n, TStreamerElement *ele)
02004 {
02005
02006
02007
02008 if (n <= 0) return;
02009
02010 Int_t l = sizeof(Float_t)*n;
02011 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
02012
02013 if (ele && ele->GetFactor()) {
02014
02015
02016
02017 Double_t factor = ele->GetFactor();
02018 Double_t xmin = ele->GetXmin();
02019 Double_t xmax = ele->GetXmax();
02020 for (int j = 0; j < n; j++) {
02021 Float_t x = f[j];
02022 if (x < xmin) x = xmin;
02023 if (x > xmax) x = xmax;
02024 UInt_t aint = UInt_t(0.5+factor*(x-xmin)); *this << aint;
02025 }
02026 } else {
02027 Int_t nbits = 0;
02028
02029 if (ele) nbits = (Int_t)ele->GetXmin();
02030 if (!nbits) nbits = 12;
02031 Int_t i;
02032
02033
02034
02035 union {
02036 Float_t xx;
02037 Int_t ix;
02038 };
02039 for (i = 0; i < n; i++) {
02040 xx = f[i];
02041 UChar_t theExp = (UChar_t)(0x000000ff & ((ix<<1)>>24));
02042 UShort_t theMan = ((1<<(nbits+1))-1) & (ix>>(23-nbits-1));
02043 theMan++;
02044 theMan = theMan>>1;
02045 if (theMan&1<<nbits) theMan = (1<<nbits) - 1;
02046 if (xx < 0) theMan |= 1<<(nbits+1);
02047 *this << theExp;
02048 *this << theMan;
02049 }
02050 }
02051 }
02052
02053
02054 void TBufferFile::WriteFastArrayDouble32(const Double_t *d, Int_t n, TStreamerElement *ele)
02055 {
02056
02057
02058
02059 if (n <= 0) return;
02060
02061 Int_t l = sizeof(Float_t)*n;
02062 if (fBufCur + l > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+l));
02063
02064 if (ele && ele->GetFactor()) {
02065
02066
02067
02068 Double_t factor = ele->GetFactor();
02069 Double_t xmin = ele->GetXmin();
02070 Double_t xmax = ele->GetXmax();
02071 for (int j = 0; j < n; j++) {
02072 Double_t x = d[j];
02073 if (x < xmin) x = xmin;
02074 if (x > xmax) x = xmax;
02075 UInt_t aint = UInt_t(0.5+factor*(x-xmin)); *this << aint;
02076 }
02077 } else {
02078 Int_t nbits = 0;
02079
02080 if (ele) nbits = (Int_t)ele->GetXmin();
02081 Int_t i;
02082 if (!nbits) {
02083
02084 for (i = 0; i < n; i++) {
02085 Float_t afloat = (Float_t)d[i];
02086 *this << afloat;
02087 }
02088 } else {
02089
02090
02091
02092 union {
02093 Float_t xx;
02094 Int_t ix;
02095 };
02096 for (i = 0; i < n; i++) {
02097 xx = (Float_t)d[i];
02098 UChar_t theExp = (UChar_t)(0x000000ff & ((ix<<1)>>24));
02099 UShort_t theMan = ((1<<(nbits+1))-1) & (ix>>(23-nbits-1));
02100 theMan++;
02101 theMan = theMan>>1;
02102 if(theMan&1<<nbits) theMan = (1<<nbits) - 1;
02103 if (xx < 0) theMan |= 1<<(nbits+1);
02104 *this << theExp;
02105 *this << theMan;
02106 }
02107 }
02108 }
02109 }
02110
02111
02112 void TBufferFile::WriteFastArray(void *start, const TClass *cl, Int_t n,
02113 TMemberStreamer *streamer)
02114 {
02115
02116
02117
02118 if (streamer) {
02119 (*streamer)(*this, start, 0);
02120 return;
02121 }
02122
02123 char *obj = (char*)start;
02124 if (!n) n=1;
02125 int size = cl->Size();
02126
02127 for(Int_t j=0; j<n; j++,obj+=size) {
02128 ((TClass*)cl)->Streamer(obj,*this);
02129 }
02130 }
02131
02132
02133 Int_t TBufferFile::WriteFastArray(void **start, const TClass *cl, Int_t n,
02134 Bool_t isPreAlloc, TMemberStreamer *streamer)
02135 {
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146 if (streamer) {
02147 (*streamer)(*this,(void*)start,0);
02148 return 0;
02149 }
02150
02151 int strInfo = 0;
02152
02153 Int_t res = 0;
02154
02155 if (!isPreAlloc) {
02156
02157 for (Int_t j=0;j<n;j++) {
02158
02159 if (!strInfo && !start[j] ) {
02160 TStreamerInfo *info = (TStreamerInfo*)((TClass*)cl)->GetStreamerInfo();
02161 ForceWriteInfo(info,kFALSE);
02162 }
02163 strInfo = 2003;
02164 res |= WriteObjectAny(start[j],cl);
02165 }
02166
02167 } else {
02168
02169 for (Int_t j=0;j<n;j++) {
02170 if (!start[j]) start[j] = ((TClass*)cl)->New();
02171 ((TClass*)cl)->Streamer(start[j],*this);
02172 }
02173
02174 }
02175 return res;
02176 }
02177
02178
02179 TObject *TBufferFile::ReadObject(const TClass * )
02180 {
02181
02182
02183
02184
02185
02186
02187
02188
02189 return (TObject*) ReadObjectAny(0);
02190 }
02191
02192
02193 void TBufferFile::SkipObjectAny()
02194 {
02195
02196
02197 UInt_t start, count;
02198 ReadVersion(&start, &count);
02199 SetBufferOffset(start+count+sizeof(UInt_t));
02200 }
02201
02202
02203 void *TBufferFile::ReadObjectAny(const TClass *clCast)
02204 {
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214 R__ASSERT(IsReading());
02215
02216
02217 InitMap();
02218
02219
02220 UInt_t startpos = UInt_t(fBufCur-fBuffer);
02221
02222
02223 UInt_t tag;
02224 TClass *clRef = ReadClass(clCast, &tag);
02225 TClass *clOnfile = 0;
02226 Int_t baseOffset = 0;
02227 if (clRef && (clRef!=(TClass*)(-1)) && clCast) {
02228
02229 baseOffset = clRef->GetBaseClassOffset(clCast);
02230 if (baseOffset == -1) {
02231
02232
02233 if (!clCast->GetSchemaRules() ||
02234 !clCast->GetSchemaRules()->HasRuleWithSourceClass(clRef->GetName()))
02235 {
02236
02237 Error("ReadObject", "got object of wrong class! requested %s but got %s",
02238 clCast->GetName(), clRef->GetName());
02239
02240 CheckByteCount(startpos, tag, (TClass*)0);
02241 return 0;
02242 }
02243 baseOffset = 0;
02244
02245 Info("ReadObjectAny","Using Converter StreamerInfo from %s to %s",clRef->GetName(),clCast->GetName());
02246 clRef = const_cast<TClass*>(clCast);
02247
02248 }
02249 if (clCast->GetClassInfo() && !clRef->GetClassInfo()) {
02250
02251 Error("ReadObject", "trying to read an emulated class (%s) to store in a compiled pointer (%s)",
02252 clRef->GetName(),clCast->GetName());
02253 CheckByteCount(startpos, tag, (TClass*)0);
02254 return 0;
02255 }
02256 }
02257
02258
02259
02260 char *obj;
02261 if (fVersion > 0) {
02262 obj = (char *) (Long_t)fMap->GetValue(startpos+kMapOffset);
02263 if (obj == (void*) -1) obj = 0;
02264 if (obj) {
02265 CheckByteCount(startpos, tag, (TClass*)0);
02266 return (obj+baseOffset);
02267 }
02268 }
02269
02270
02271 if (clRef == (TClass*) -1) {
02272 if (fBufCur >= fBufMax) return 0;
02273 if (fVersion > 0)
02274 MapObject((TObject*) -1, startpos+kMapOffset);
02275 else
02276 MapObject((void*)0, 0, fMapCount);
02277 CheckByteCount(startpos, tag, (TClass*)0);
02278 return 0;
02279 }
02280
02281 if (!clRef) {
02282
02283
02284 if (fVersion > 0) {
02285 tag += fDisplacement;
02286 tag = CheckObject(tag, clCast);
02287 } else {
02288 if (tag > (UInt_t)fMap->GetSize()) {
02289 Error("ReadObject", "object tag too large, I/O buffer corrupted");
02290 return 0;
02291
02292 }
02293 }
02294 obj = (char *) (Long_t)fMap->GetValue(tag);
02295 clRef = (TClass*) (Long_t)fClassMap->GetValue(tag);
02296
02297 if (clRef && (clRef!=(TClass*)(-1)) && clCast) {
02298
02299 baseOffset = clRef->GetBaseClassOffset(clCast);
02300 if (baseOffset == -1) {
02301 Error("ReadObject", "Got object of wrong class (Got %s while expecting %s)",
02302 clRef->GetName(),clCast->GetName());
02303
02304 baseOffset = 0;
02305 }
02306 }
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316 } else {
02317
02318
02319 obj = (char*)clRef->New();
02320 if (!obj) {
02321 Error("ReadObject", "could not create object of class %s",
02322 clRef->GetName());
02323
02324 return 0;
02325 }
02326
02327
02328 if (fVersion > 0)
02329 MapObject(obj, clRef, startpos+kMapOffset);
02330 else
02331 MapObject(obj, clRef, fMapCount);
02332
02333
02334 clRef->Streamer( obj, *this, clOnfile );
02335
02336 CheckByteCount(startpos, tag, clRef);
02337 }
02338
02339 return obj+baseOffset;
02340 }
02341
02342
02343 void TBufferFile::WriteObject(const TObject *obj)
02344 {
02345
02346
02347 WriteObjectAny(obj, TObject::Class());
02348 }
02349
02350
02351 void TBufferFile::WriteObjectClass(const void *actualObjectStart, const TClass *actualClass)
02352 {
02353
02354
02355
02356
02357 R__ASSERT(IsWriting());
02358
02359 if (!actualObjectStart) {
02360
02361
02362 *this << kNullTag;
02363
02364 } else {
02365
02366
02367 InitMap();
02368
02369 ULong_t idx;
02370 UInt_t slot;
02371 ULong_t hash = Void_Hash(actualObjectStart);
02372
02373 if ((idx = (ULong_t)fMap->GetValue(hash, (Long_t)actualObjectStart, slot)) != 0) {
02374
02375
02376
02377 UInt_t objIdx = UInt_t(idx);
02378
02379
02380 *this << objIdx;
02381
02382 } else {
02383
02384
02385
02386 if (actualClass->HasDefaultConstructor() == 0) {
02387 Warning("WriteObjectAny", "since %s has no public constructor\n"
02388 "\twhich can be called without argument, objects of this class\n"
02389 "\tcan not be read with the current library. You will need to\n"
02390 "\tadd a default constructor before attempting to read it.",
02391 actualClass->GetName());
02392 }
02393
02394
02395 UInt_t cntpos = UInt_t(fBufCur-fBuffer);
02396 fBufCur += sizeof(UInt_t);
02397
02398
02399 Int_t mapsize = fMap->Capacity();
02400 WriteClass(actualClass);
02401
02402
02403
02404
02405 UInt_t offset = cntpos+kMapOffset;
02406 if (mapsize == fMap->Capacity()) {
02407 fMap->AddAt(slot, hash, (Long_t)actualObjectStart, offset);
02408 } else {
02409
02410 fMap->Add(hash, (Long_t)actualObjectStart, offset);
02411 }
02412
02413
02414 fMapCount++;
02415
02416 ((TClass*)actualClass)->Streamer((void*)actualObjectStart,*this);
02417
02418
02419 SetByteCount(cntpos);
02420 }
02421 }
02422 }
02423
02424 namespace {
02425 struct DynamicType {
02426
02427
02428
02429 virtual ~DynamicType() {}
02430 };
02431 }
02432
02433
02434 Int_t TBufferFile::WriteObjectAny(const void *obj, const TClass *ptrClass)
02435 {
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445 if (!obj) {
02446 WriteObjectClass(0, 0);
02447 return 1;
02448 }
02449
02450 if (!ptrClass) {
02451 Error("WriteObjectAny", "ptrClass argument may not be 0");
02452 return 0;
02453 }
02454
02455 TClass *clActual = ptrClass->GetActualClass(obj);
02456
02457 if (clActual==0) {
02458
02459
02460
02461 DynamicType* d_ptr = (DynamicType*)obj;
02462 Warning("WriteObjectAny",
02463 "An object of type %s (from type_info) passed through a %s pointer was truncated (due a missing dictionary)!!!",
02464 typeid(*d_ptr).name(),ptrClass->GetName());
02465 WriteObjectClass(obj, ptrClass);
02466 return 2;
02467 } else if (clActual && (clActual != ptrClass)) {
02468 const char *temp = (const char*) obj;
02469 temp -= clActual->GetBaseClassOffset(ptrClass);
02470 WriteObjectClass(temp, clActual);
02471 return 1;
02472 } else {
02473 WriteObjectClass(obj, ptrClass);
02474 return 1;
02475 }
02476 }
02477
02478
02479 TClass *TBufferFile::ReadClass(const TClass *clReq, UInt_t *objTag)
02480 {
02481
02482
02483
02484
02485 R__ASSERT(IsReading());
02486
02487
02488 TClass *cl;
02489 if (fBufCur < fBuffer || fBufCur > fBufMax) {
02490 fBufCur = fBufMax;
02491 cl = (TClass*)-1;
02492 return cl;
02493 }
02494 UInt_t bcnt, tag, startpos = 0;
02495 *this >> bcnt;
02496 if (!(bcnt & kByteCountMask) || bcnt == kNewClassTag) {
02497 tag = bcnt;
02498 bcnt = 0;
02499 } else {
02500 fVersion = 1;
02501 startpos = UInt_t(fBufCur-fBuffer);
02502 *this >> tag;
02503 }
02504
02505
02506 if (!(tag & kClassMask)) {
02507 if (objTag) *objTag = tag;
02508 return 0;
02509 }
02510
02511 if (tag == kNewClassTag) {
02512
02513
02514
02515
02516 cl = TClass::Load(*this);
02517
02518
02519 if (fVersion > 0) {
02520
02521 TClass *cl1 = (TClass *)(Long_t)fMap->GetValue(startpos+kMapOffset);
02522 if (cl1 != cl)
02523 MapObject(cl ? cl : (TObject*) -1, startpos+kMapOffset);
02524 } else
02525 MapObject(cl, fMapCount);
02526
02527 } else {
02528
02529
02530 UInt_t clTag = (tag & ~kClassMask);
02531
02532 if (fVersion > 0) {
02533 clTag += fDisplacement;
02534 clTag = CheckObject(clTag, clReq, kTRUE);
02535 } else {
02536 if (clTag == 0 || clTag > (UInt_t)fMap->GetSize()) {
02537 Error("ReadClass", "illegal class tag=%d (0<tag<=%d), I/O buffer corrupted",
02538 clTag, fMap->GetSize());
02539
02540 }
02541 }
02542
02543
02544 cl = (TClass *)(Long_t)fMap->GetValue(clTag);
02545 }
02546
02547 if (cl && clReq &&
02548 (!cl->InheritsFrom(clReq) &&
02549 !(clReq->GetSchemaRules() &&
02550 clReq->GetSchemaRules()->HasRuleWithSourceClass(cl->GetName()) )
02551 ) ) {
02552 Error("ReadClass", "got wrong class: %s", cl->GetName());
02553
02554 }
02555
02556
02557 if (objTag) *objTag = (bcnt & ~kByteCountMask);
02558
02559
02560 if (!cl) cl = (TClass*)-1;
02561
02562 return cl;
02563 }
02564
02565
02566 void TBufferFile::WriteClass(const TClass *cl)
02567 {
02568
02569
02570 R__ASSERT(IsWriting());
02571
02572 ULong_t idx;
02573 ULong_t hash = Void_Hash(cl);
02574 UInt_t slot;
02575
02576 if ((idx = (ULong_t)fMap->GetValue(hash, (Long_t)cl,slot)) != 0) {
02577
02578
02579
02580 UInt_t clIdx = UInt_t(idx);
02581
02582
02583 *this << (clIdx | kClassMask);
02584
02585 } else {
02586
02587
02588 UInt_t offset = UInt_t(fBufCur-fBuffer);
02589
02590
02591 *this << kNewClassTag;
02592
02593
02594 cl->Store(*this);
02595
02596
02597 CheckCount(offset+kMapOffset);
02598 fMap->AddAt(slot, hash, (Long_t)cl, offset+kMapOffset);
02599 fMapCount++;
02600 }
02601 }
02602
02603
02604 void TBufferFile::SkipVersion(const TClass *cl)
02605 {
02606
02607
02608 Version_t version;
02609
02610
02611 frombuf(this->fBufCur,&version);
02612
02613
02614 if (version & kByteCountVMask) {
02615 frombuf(this->fBufCur,&version);
02616 frombuf(this->fBufCur,&version);
02617 }
02618
02619 if (cl && cl->GetClassVersion() != 0 && version<=1) {
02620 if (version <= 0) {
02621 UInt_t checksum = 0;
02622
02623 frombuf(this->fBufCur,&checksum);
02624 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
02625 if (vinfo) {
02626 return;
02627 } else {
02628
02629
02630
02631
02632 if (checksum==cl->GetCheckSum() || checksum==cl->GetCheckSum(1)) {
02633 version = cl->GetClassVersion();
02634 } else {
02635 if (fParent) {
02636 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
02637 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
02638 } else {
02639 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\"( buffer with no parent)",
02640 checksum, cl->GetName());
02641 }
02642 return;
02643 }
02644 }
02645 } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 ) {
02646
02647
02648 if ((!cl->IsLoaded() || cl->IsForeign()) &&
02649 cl->GetStreamerInfos()->GetLast()>1 ) {
02650
02651 const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
02652 const TStreamerInfo *local = (TStreamerInfo*)list->FindObject(cl->GetName());
02653 if ( local ) {
02654 UInt_t checksum = local->GetCheckSum();
02655 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
02656 if (vinfo) {
02657 version = vinfo->GetClassVersion();
02658 } else {
02659 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
02660 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
02661 return;
02662 }
02663 }
02664 else {
02665 Error("ReadVersion", "Class %s not known to file %s.",
02666 cl->GetName(), ((TFile*)fParent)->GetName());
02667 version = 0;
02668 }
02669 }
02670 }
02671 }
02672 }
02673
02674
02675 Version_t TBufferFile::ReadVersion(UInt_t *startpos, UInt_t *bcnt, const TClass *cl)
02676 {
02677
02678
02679 Version_t version;
02680
02681 if (startpos && bcnt) {
02682
02683 *startpos = UInt_t(fBufCur-fBuffer);
02684
02685
02686
02687
02688
02689 union {
02690 UInt_t cnt;
02691 Version_t vers[2];
02692 } v;
02693 #ifdef R__BYTESWAP
02694 frombuf(this->fBufCur,&v.vers[1]);
02695 frombuf(this->fBufCur,&v.vers[0]);
02696 #else
02697 frombuf(this->fBufCur,&v.vers[0]);
02698 frombuf(this->fBufCur,&v.vers[1]);
02699 #endif
02700
02701
02702 if (!(v.cnt & kByteCountMask)) {
02703 fBufCur -= sizeof(UInt_t);
02704 v.cnt = 0;
02705 }
02706 *bcnt = (v.cnt & ~kByteCountMask);
02707 frombuf(this->fBufCur,&version);
02708
02709 } else {
02710
02711
02712 frombuf(this->fBufCur,&version);
02713
02714
02715 if (version & kByteCountVMask) {
02716 frombuf(this->fBufCur,&version);
02717 frombuf(this->fBufCur,&version);
02718 }
02719 }
02720 if (version<=1) {
02721 if (version <= 0) {
02722 if (cl) {
02723 if (cl->GetClassVersion() != 0) {
02724 UInt_t checksum = 0;
02725
02726 frombuf(this->fBufCur,&checksum);
02727 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
02728 if (vinfo) {
02729 return vinfo->TStreamerInfo::GetClassVersion();
02730 } else {
02731
02732
02733
02734
02735 if (checksum==cl->GetCheckSum() || checksum==cl->GetCheckSum(1)) {
02736 version = cl->GetClassVersion();
02737 } else {
02738 if (fParent) {
02739 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
02740 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
02741 } else {
02742 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\"( buffer with no parent)",
02743 checksum, cl->GetName());
02744 }
02745 return 0;
02746 }
02747 }
02748 }
02749 } else {
02750 UInt_t checksum = 0;
02751
02752 frombuf(this->fBufCur,&checksum);
02753 }
02754 } else if (version == 1 && fParent && ((TFile*)fParent)->GetVersion()<40000 && cl && cl->GetClassVersion() != 0) {
02755
02756
02757 if ((!cl->IsLoaded() || cl->IsForeign()) &&
02758 cl->GetStreamerInfos()->GetLast()>1 ) {
02759
02760 const TList *list = ((TFile*)fParent)->GetStreamerInfoCache();
02761 const TStreamerInfo *local = (TStreamerInfo*)list->FindObject(cl->GetName());
02762 if ( local ) {
02763 UInt_t checksum = local->GetCheckSum();
02764 TStreamerInfo *vinfo = (TStreamerInfo*)cl->FindStreamerInfo(checksum);
02765 if (vinfo) {
02766 version = vinfo->GetClassVersion();
02767 } else {
02768 Error("ReadVersion", "Could not find the StreamerInfo with a checksum of %d for the class \"%s\" in %s.",
02769 checksum, cl->GetName(), ((TFile*)fParent)->GetName());
02770 return 0;
02771 }
02772 }
02773 else {
02774 Error("ReadVersion", "Class %s not known to file %s.",
02775 cl->GetName(), ((TFile*)fParent)->GetName());
02776 version = 0;
02777 }
02778 }
02779 }
02780 }
02781 return version;
02782 }
02783
02784
02785 UInt_t TBufferFile::WriteVersion(const TClass *cl, Bool_t useBcnt)
02786 {
02787
02788
02789 UInt_t cntpos = 0;
02790 if (useBcnt) {
02791
02792 cntpos = UInt_t(fBufCur-fBuffer);
02793 fBufCur += sizeof(UInt_t);
02794 }
02795
02796 Version_t version = cl->GetClassVersion();
02797 if (version<=1 && cl->IsForeign()) {
02798 *this << Version_t(0);
02799 *this << cl->GetCheckSum();
02800 } else {
02801 if (version > kMaxVersion) {
02802 Error("WriteVersion", "version number cannot be larger than %hd)",
02803 kMaxVersion);
02804 version = kMaxVersion;
02805 }
02806 *this <<version;
02807 }
02808
02809
02810 return cntpos;
02811 }
02812
02813
02814 UInt_t TBufferFile::WriteVersionMemberWise(const TClass *cl, Bool_t useBcnt)
02815 {
02816
02817
02818
02819 UInt_t cntpos = 0;
02820 if (useBcnt) {
02821
02822 cntpos = UInt_t(fBufCur-fBuffer);
02823 fBufCur += sizeof(UInt_t);
02824 }
02825
02826 Version_t version = cl->GetClassVersion();
02827 if (version<=1 && cl->IsForeign()) {
02828 Error("WriteVersionMemberWise", "Member-wise streaming of foreign collection not yet implemented!");
02829 *this << Version_t(0);
02830 *this << cl->GetCheckSum();
02831 } else {
02832 if (version > kMaxVersion) {
02833 Error("WriteVersionMemberWise", "version number cannot be larger than %hd)",
02834 kMaxVersion);
02835 version = kMaxVersion;
02836 }
02837 version |= kStreamedMemberWise;
02838 *this <<version;
02839 }
02840
02841
02842 return cntpos;
02843 }
02844
02845
02846 void TBufferFile::StreamObject(void *obj, const type_info &typeinfo, const TClass* onFileClass )
02847 {
02848
02849
02850 TClass *cl = TClass::GetClass(typeinfo);
02851 cl->Streamer(obj, *this, (TClass*)onFileClass );
02852 }
02853
02854
02855 void TBufferFile::StreamObject(void *obj, const char *className, const TClass* onFileClass)
02856 {
02857
02858
02859 TClass *cl = TClass::GetClass(className);
02860 cl->Streamer(obj, *this, (TClass*)onFileClass );
02861 }
02862
02863
02864 void TBufferFile::StreamObject(void *obj, const TClass *cl, const TClass* onFileClass )
02865 {
02866
02867
02868 ((TClass*)cl)->Streamer(obj, *this, (TClass*)onFileClass );
02869 }
02870
02871
02872 void TBufferFile::StreamObject(TObject *obj)
02873 {
02874
02875
02876 obj->Streamer(*this);
02877 }
02878
02879
02880 void TBufferFile::CheckCount(UInt_t offset)
02881 {
02882
02883
02884 if (IsWriting()) {
02885 if (offset >= kMaxMapCount) {
02886 Error("CheckCount", "buffer offset too large (larger than %d)", kMaxMapCount);
02887
02888 }
02889 }
02890 }
02891
02892
02893 UInt_t TBufferFile::CheckObject(UInt_t offset, const TClass *cl, Bool_t readClass)
02894 {
02895
02896
02897
02898
02899
02900
02901 if (!offset) return offset;
02902
02903 Long_t cli;
02904
02905 if (readClass) {
02906 if ((cli = fMap->GetValue(offset)) == 0) {
02907
02908
02909
02910
02911 char *bufsav = fBufCur;
02912 fBufCur = (char *)(fBuffer + offset-kMapOffset-sizeof(UInt_t));
02913
02914 TClass *c = ReadClass(cl);
02915 if (c == (TClass*) -1) {
02916
02917 fMap->Remove(offset);
02918 fMap->Add(offset, -1);
02919 offset = 0;
02920 if (cl)
02921 Warning("CheckObject", "reference to unavailable class %s,"
02922 " pointers of this type will be 0", cl->GetName());
02923 else
02924 Warning("CheckObject", "reference to an unavailable class,"
02925 " pointers of that type will be 0");
02926 }
02927
02928 fBufCur = bufsav;
02929
02930 } else if (cli == -1) {
02931
02932
02933 return 0;
02934 }
02935
02936 } else {
02937
02938 if ((cli = fMap->GetValue(offset)) == 0) {
02939
02940
02941
02942
02943 char *bufsav = fBufCur;
02944 fBufCur = (char *)(fBuffer + offset-kMapOffset);
02945
02946 TObject *obj = ReadObject(cl);
02947 if (!obj) {
02948
02949 fMap->Remove(offset);
02950 fMap->Add(offset, -1);
02951 Warning("CheckObject", "reference to object of unavailable class %s, offset=%d"
02952 " pointer will be 0", cl ? cl->GetName() : "TObject",offset);
02953 offset = 0;
02954 }
02955
02956 fBufCur = bufsav;
02957
02958 } else if (cli == -1) {
02959
02960
02961 return 0;
02962 }
02963
02964 }
02965
02966 return offset;
02967 }
02968
02969
02970 Bool_t TBufferFile::CheckObject(const TObject *obj)
02971 {
02972
02973
02974
02975
02976 return CheckObject(obj, TObject::Class());
02977 }
02978
02979
02980 Bool_t TBufferFile::CheckObject(const void *obj, const TClass *ptrClass)
02981 {
02982
02983
02984
02985
02986 if (!obj || !fMap || !ptrClass) return kFALSE;
02987
02988 TClass *clActual = ptrClass->GetActualClass(obj);
02989
02990 ULong_t idx;
02991
02992 if (clActual && (ptrClass != clActual)) {
02993 const char *temp = (const char*) obj;
02994 temp -= clActual->GetBaseClassOffset(ptrClass);
02995 idx = (ULong_t)fMap->GetValue(Void_Hash(temp), (Long_t)temp);
02996 } else {
02997 idx = (ULong_t)fMap->GetValue(Void_Hash(obj), (Long_t)obj);
02998 }
02999
03000 return idx ? kTRUE : kFALSE;
03001 }
03002
03003
03004 void TBufferFile::SetPidOffset(UShort_t offset)
03005 {
03006
03007
03008
03009
03010
03011
03012
03013 fPidOffset = offset;
03014 }
03015
03016
03017 void TBufferFile::GetMappedObject(UInt_t tag, void* &ptr, TClass* &ClassPtr) const
03018 {
03019
03020
03021
03022
03023 if (tag > (UInt_t)fMap->GetSize()) {
03024 ptr = 0;
03025 ClassPtr = 0;
03026 } else {
03027 ptr = (void*)(Long_t)fMap->GetValue(tag);
03028 ClassPtr = (TClass*) (Long_t)fClassMap->GetValue(tag);
03029 }
03030 }
03031
03032
03033 void TBufferFile::MapObject(const TObject *obj, UInt_t offset)
03034 {
03035
03036
03037
03038
03039
03040
03041
03042 if (IsWriting()) {
03043 if (!fMap) InitMap();
03044
03045 if (obj) {
03046 CheckCount(offset);
03047 ULong_t hash = Void_Hash(obj);
03048 fMap->Add(hash, (Long_t)obj, offset);
03049
03050
03051 fMapCount++;
03052 }
03053 } else {
03054 if (!fMap || !fClassMap) InitMap();
03055
03056 fMap->Add(offset, (Long_t)obj);
03057 fClassMap->Add(offset,
03058 (obj && obj != (TObject*)-1) ? (Long_t)((TObject*)obj)->IsA() : 0);
03059 fMapCount++;
03060 }
03061 }
03062
03063
03064 void TBufferFile::MapObject(const void *obj, const TClass* cl, UInt_t offset)
03065 {
03066
03067
03068
03069
03070
03071
03072
03073 if (IsWriting()) {
03074 if (!fMap) InitMap();
03075
03076 if (obj) {
03077 CheckCount(offset);
03078 ULong_t hash = Void_Hash(obj);
03079 fMap->Add(hash, (Long_t)obj, offset);
03080
03081
03082 fMapCount++;
03083 }
03084 } else {
03085 if (!fMap || !fClassMap) InitMap();
03086
03087 fMap->Add(offset, (Long_t)obj);
03088 fClassMap->Add(offset, (Long_t)cl);
03089 fMapCount++;
03090 }
03091 }
03092
03093
03094 void TBufferFile::SetReadParam(Int_t mapsize)
03095 {
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106 R__ASSERT(IsReading());
03107 R__ASSERT(fMap == 0);
03108
03109 fMapSize = mapsize;
03110 }
03111
03112
03113 void TBufferFile::SetWriteParam(Int_t mapsize)
03114 {
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126 R__ASSERT(IsWriting());
03127 R__ASSERT(fMap == 0);
03128
03129 fMapSize = mapsize;
03130 }
03131
03132
03133 void TBufferFile::InitMap()
03134 {
03135
03136
03137
03138 if (IsWriting()) {
03139 if (!fMap) {
03140 fMap = new TExMap(fMapSize);
03141
03142
03143 fMapCount = 0;
03144 }
03145 } else {
03146 if (!fMap) {
03147 fMap = new TExMap(fMapSize);
03148 fMap->Add(0, kNullTag);
03149 fMapCount = 1;
03150 } else if (fMapCount==0) {
03151 fMap->Add(0, kNullTag);
03152 fMapCount = 1;
03153 }
03154 if (!fClassMap) {
03155 fClassMap = new TExMap(fMapSize);
03156 fClassMap->Add(0, kNullTag);
03157 }
03158 }
03159 }
03160
03161
03162 void TBufferFile::ResetMap()
03163 {
03164
03165
03166 if (fMap) fMap->Delete();
03167 if (fClassMap) fClassMap->Delete();
03168 fMapCount = 0;
03169 fDisplacement = 0;
03170
03171
03172 ResetBit(kUser1);
03173 ResetBit(kUser2);
03174 ResetBit(kUser3);
03175 }
03176
03177
03178 Int_t TBufferFile::ReadBuf(void *buf, Int_t max)
03179 {
03180
03181
03182
03183 R__ASSERT(IsReading());
03184
03185 if (max == 0) return 0;
03186
03187 Int_t n = TMath::Min(max, (Int_t)(fBufMax - fBufCur));
03188
03189 memcpy(buf, fBufCur, n);
03190 fBufCur += n;
03191
03192 return n;
03193 }
03194
03195
03196 void TBufferFile::WriteBuf(const void *buf, Int_t max)
03197 {
03198
03199
03200 R__ASSERT(IsWriting());
03201
03202 if (max == 0) return;
03203
03204 if (fBufCur + max > fBufMax) Expand(TMath::Max(2*fBufSize, fBufSize+max));
03205
03206 memcpy(fBufCur, buf, max);
03207 fBufCur += max;
03208 }
03209
03210
03211 char *TBufferFile::ReadString(char *s, Int_t max)
03212 {
03213
03214
03215
03216
03217
03218 R__ASSERT(IsReading());
03219
03220 char ch;
03221 Int_t nr = 0;
03222
03223 if (max == -1) max = kMaxInt;
03224
03225 while (nr < max-1) {
03226
03227 *this >> ch;
03228
03229
03230 if (ch == 0) break;
03231
03232 s[nr++] = ch;
03233 }
03234
03235 s[nr] = 0;
03236 return s;
03237 }
03238
03239
03240 void TBufferFile::WriteString(const char *s)
03241 {
03242
03243
03244
03245 WriteBuf(s, (strlen(s)+1)*sizeof(char));
03246 }
03247
03248
03249 TProcessID *TBufferFile::GetLastProcessID(TRefTable *reftable) const
03250 {
03251
03252
03253 TFile *file = (TFile*)GetParent();
03254
03255 if (file && !reftable->TestBit(TRefTable::kHaveWarnedReadingOld) && file->GetNProcessIDs()>1) {
03256 Warning("ReadBuffer", "The file was written during several processes with an "
03257 "older ROOT version; the TRefTable entries might be inconsistent.");
03258 reftable->SetBit(TRefTable::kHaveWarnedReadingOld);
03259 }
03260
03261
03262 TProcessID *fileProcessID = TProcessID::GetProcessID(0);
03263 if (file && file->GetNProcessIDs() > 0) {
03264
03265 fileProcessID = (TProcessID *) file->GetListOfProcessIDs()->Last();
03266 }
03267 return fileProcessID;
03268 }
03269
03270
03271 TProcessID *TBufferFile::ReadProcessID(UShort_t pidf)
03272 {
03273
03274
03275
03276 TFile *file = (TFile*)GetParent();
03277 if (!file) {
03278 if (!pidf) return TProcessID::GetPID();
03279 return 0;
03280 }
03281 return file->ReadProcessID(pidf);
03282 }
03283
03284
03285 UInt_t TBufferFile::GetTRefExecId()
03286 {
03287
03288
03289
03290
03291
03292
03293 return TStreamerInfo::GetCurrentElement()->GetUniqueID();
03294 }
03295
03296
03297 UShort_t TBufferFile::WriteProcessID(TProcessID *pid)
03298 {
03299
03300
03301
03302 TFile *file = (TFile*)GetParent();
03303 if (!file) return 0;
03304 return file->WriteProcessID(pid);
03305 }
03306
03307
03308
03309
03310 void TBufferFile::ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t force)
03311 {
03312
03313
03314 if (info) info->ForceWriteInfo((TFile*)GetParent(),force);
03315 }
03316
03317
03318
03319 void TBufferFile::ForceWriteInfoClones(TClonesArray *a)
03320 {
03321
03322
03323
03324
03325
03326 TStreamerInfo *sinfo = (TStreamerInfo*)a->GetClass()->GetStreamerInfo();
03327 if (sinfo->IsOptimized()) {
03328 sinfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
03329 sinfo->Compile();
03330 }
03331 ForceWriteInfo(sinfo,kFALSE);
03332 }
03333
03334
03335 Int_t TBufferFile::ReadClones(TClonesArray *a, Int_t nobjects, Version_t objvers)
03336 {
03337
03338
03339 char **arr = (char **)a->GetObjectRef(0);
03340 char **end = arr + nobjects;
03341
03342 TStreamerInfo *info = (TStreamerInfo*)a->GetClass()->GetStreamerInfo(objvers);
03343
03344 return ReadSequenceVecPtr(*(info->GetReadMemberWiseActions(kTRUE)),arr,end);
03345 }
03346
03347
03348 Int_t TBufferFile::WriteClones(TClonesArray *a, Int_t nobjects)
03349 {
03350
03351
03352 char **arr = reinterpret_cast<char**>(a->GetObjectRef(0));
03353
03354 TStreamerInfo *info = (TStreamerInfo*)a->GetClass()->GetStreamerInfo();
03355 return info->WriteBufferAux(*this,arr,-1,nobjects,0,1);
03356 }
03357
03358
03359 Int_t TBufferFile::ReadClassEmulated(const TClass *cl, void *object, const TClass *onFileClass)
03360 {
03361
03362
03363 UInt_t start,count;
03364
03365
03366 Version_t v = ReadVersion(&start,&count);
03367 void *ptr = &object;
03368 if (count) {
03369 TStreamerInfo *sinfo = 0;
03370 if( onFileClass ) {
03371 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, v );
03372 if( !sinfo )
03373 return 0;
03374 }
03375
03376 sinfo = (TStreamerInfo*)cl->GetStreamerInfo(v);
03377 sinfo->ReadBuffer(*this,(char**)ptr,-1);
03378 if (sinfo->IsRecovered()) count=0;
03379 CheckByteCount(start,count,cl);
03380 } else {
03381 SetBufferOffset(start);
03382 ((TStreamerInfo*)cl->GetStreamerInfo())->ReadBuffer(*this,(char**)ptr,-1);
03383 }
03384 return 0;
03385 }
03386
03387
03388 Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, Int_t version, UInt_t start, UInt_t count, const TClass *onFileClass)
03389 {
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402 TObjArray *infos = cl->GetStreamerInfos();
03403 Int_t ninfos = infos->GetSize();
03404 if (version < -1 || version >= ninfos) {
03405 Error("ReadBuffer1", "class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
03406 cl->GetName(), version, Length() );
03407 CheckByteCount(start, count, cl);
03408 return 0;
03409 }
03410
03411
03412
03413 TStreamerInfo *sinfo = 0;
03414 if( onFileClass ) {
03415 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, version );
03416 if( !sinfo ) {
03417 Error("ReadClassBuffer",
03418 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
03419 onFileClass->GetName(), version, cl->GetName(), Length() );
03420 CheckByteCount(start, count, onFileClass);
03421 return 0;
03422 }
03423 }
03424
03425
03426
03427 else {
03428
03429 sinfo = (TStreamerInfo*)infos->At(version);
03430 if (sinfo == 0) {
03431
03432
03433
03434
03435
03436 if ( version == cl->GetClassVersion() || version == 1 ) {
03437 const_cast<TClass*>(cl)->BuildRealData(pointer);
03438 sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
03439 infos->AddAtAndExpand(sinfo, version);
03440 if (gDebug > 0) printf("Creating StreamerInfo for class: %s, version: %d\n", cl->GetName(), version);
03441 sinfo->Build();
03442 } else {
03443 Error("ReadClassBuffer", "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
03444 version, cl->GetName(), Length() );
03445 CheckByteCount(start, count, cl);
03446 return 0;
03447 }
03448 } else if (!sinfo->IsCompiled()) {
03449
03450
03451 const_cast<TClass*>(cl)->BuildRealData(pointer);
03452 sinfo->BuildOld();
03453 }
03454 }
03455
03456
03457 ReadSequence(*(sinfo->GetReadObjectWiseActions()), (char*)pointer);
03458 if (sinfo->IsRecovered()) count=0;
03459
03460
03461 CheckByteCount(start, count, cl);
03462 return 0;
03463 }
03464
03465
03466 Int_t TBufferFile::ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onFileClass)
03467 {
03468
03469
03470
03471
03472
03473
03474
03475 UInt_t R__s = 0;
03476 UInt_t R__c = 0;
03477 Version_t version;
03478
03479 if( onFileClass )
03480 version = ReadVersion(&R__s, &R__c, onFileClass);
03481 else
03482 version = ReadVersion(&R__s, &R__c, cl);
03483
03484 Bool_t v2file = kFALSE;
03485 TFile *file = (TFile*)GetParent();
03486 if (file && file->GetVersion() < 30000) {
03487 version = -1;
03488 v2file = kTRUE;
03489 }
03490
03491
03492
03493
03494 TStreamerInfo *sinfo = 0;
03495 if( onFileClass ) {
03496 sinfo = (TStreamerInfo*)cl->GetConversionStreamerInfo( onFileClass, version );
03497 if( !sinfo ) {
03498 Error("ReadClassBuffer",
03499 "Could not find the right streamer info to convert %s version %d into a %s, object skipped at offset %d",
03500 onFileClass->GetName(), version, cl->GetName(), Length() );
03501 CheckByteCount(R__s, R__c, onFileClass);
03502 return 0;
03503 }
03504 }
03505
03506
03507
03508 else {
03509
03510 TObjArray *infos = cl->GetStreamerInfos();
03511 Int_t infocapacity = infos->Capacity();
03512 if (infocapacity) {
03513 if (version < -1 || version >= infocapacity) {
03514 Error("ReadClassBuffer","class: %s, attempting to access a wrong version: %d, object skipped at offset %d",
03515 cl->GetName(), version, Length());
03516 CheckByteCount(R__s, R__c, cl);
03517 return 0;
03518 }
03519 sinfo = (TStreamerInfo*) infos->UncheckedAt(version);
03520 }
03521 if (sinfo == 0) {
03522
03523
03524
03525
03526
03527
03528 if (v2file || version == cl->GetClassVersion() || version == 1 ) {
03529 const_cast<TClass*>(cl)->BuildRealData(pointer);
03530 sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
03531 infos->AddAtAndExpand(sinfo,version);
03532 if (gDebug > 0) printf("Creating StreamerInfo for class: %s, version: %d\n", cl->GetName(), version);
03533 sinfo->Build();
03534
03535 if (v2file) sinfo->BuildEmulated(file);
03536 } else {
03537 Error( "ReadClassBuffer", "Could not find the StreamerInfo for version %d of the class %s, object skipped at offset %d",
03538 version, cl->GetName(), Length() );
03539 CheckByteCount(R__s, R__c, cl);
03540 return 0;
03541 }
03542 }
03543 else if (!sinfo->IsCompiled())
03544 {
03545
03546
03547 const_cast<TClass*>(cl)->BuildRealData(pointer);
03548 sinfo->BuildOld();
03549 }
03550 }
03551
03552
03553 ReadSequence(*(sinfo->GetReadObjectWiseActions()), (char*)pointer );
03554 if (sinfo->TStreamerInfo::IsRecovered()) R__c=0;
03555
03556
03557 CheckByteCount(R__s, R__c, cl);
03558
03559 if (gDebug > 2) printf(" ReadBuffer for class: %s has read %d bytes\n", cl->GetName(), R__c);
03560
03561 return 0;
03562 }
03563
03564
03565 Int_t TBufferFile::WriteClassBuffer(const TClass *cl, void *pointer)
03566 {
03567
03568
03569
03570
03571
03572
03573
03574 TStreamerInfo *sinfo = (TStreamerInfo*)const_cast<TClass*>(cl)->GetCurrentStreamerInfo();
03575 if (sinfo == 0) {
03576 const_cast<TClass*>(cl)->BuildRealData(pointer);
03577 sinfo = new TStreamerInfo(const_cast<TClass*>(cl));
03578 const_cast<TClass*>(cl)->SetCurrentStreamerInfo(sinfo);
03579 cl->GetStreamerInfos()->AddAtAndExpand(sinfo,cl->GetClassVersion());
03580 if (gDebug > 0) printf("Creating StreamerInfo for class: %s, version: %d\n",cl->GetName(),cl->GetClassVersion());
03581 sinfo->Build();
03582 } else if (!sinfo->IsCompiled()) {
03583 const_cast<TClass*>(cl)->BuildRealData(pointer);
03584 sinfo->BuildOld();
03585 }
03586
03587
03588 UInt_t R__c = WriteVersion(cl, kTRUE);
03589
03590
03591 void *ptr = &pointer;
03592 sinfo->WriteBufferAux(*this,(char**)ptr,-1,1,0,0);
03593
03594
03595 SetByteCount(R__c, kTRUE);
03596
03597 if (gDebug > 2) printf(" WriteBuffer for class: %s version %d has written %d bytes\n",cl->GetName(),cl->GetClassVersion(),UInt_t(fBufCur - fBuffer) - R__c - (UInt_t)sizeof(UInt_t));
03598 return 0;
03599 }
03600
03601
03602 Int_t TBufferFile::ReadSequence(const TStreamerInfoActions::TActionSequence &sequence, void *obj)
03603 {
03604
03605
03606
03607 if (gDebug) {
03608
03609 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03610 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03611 iter != end;
03612 ++iter) {
03613 (*iter).PrintDebug(*this,obj);
03614 (*iter)(*this,obj);
03615 }
03616
03617 } else {
03618
03619 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03620 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03621 iter != end;
03622 ++iter) {
03623 (*iter)(*this,obj);
03624 }
03625 }
03626
03627 return 0;
03628 }
03629
03630
03631 Int_t TBufferFile::ReadSequenceVecPtr(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
03632 {
03633
03634
03635
03636 if (gDebug) {
03637
03638 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03639 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03640 iter != end;
03641 ++iter) {
03642 (*iter).PrintDebug(*this,*(char**)start_collection);
03643 (*iter)(*this,start_collection,end_collection);
03644 }
03645
03646 } else {
03647
03648 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03649 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03650 iter != end;
03651 ++iter) {
03652 (*iter)(*this,start_collection,end_collection);
03653 }
03654 }
03655
03656 return 0;
03657 }
03658
03659
03660 Int_t TBufferFile::ReadSequence(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection)
03661 {
03662
03663
03664 TStreamerInfoActions::TLoopConfiguration *loopconfig = sequence.fLoopConfig;
03665 if (gDebug) {
03666
03667
03668
03669
03670 void *arr0 = loopconfig->GetFirstAddress(start_collection,end_collection);
03671
03672 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03673 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03674 iter != end;
03675 ++iter) {
03676 (*iter).PrintDebug(*this,arr0);
03677 (*iter)(*this,start_collection,end_collection,loopconfig);
03678 }
03679
03680 } else {
03681
03682 TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03683 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03684 iter != end;
03685 ++iter) {
03686 (*iter)(*this,start_collection,end_collection,loopconfig);
03687 }
03688 }
03689
03690 return 0;
03691 }
03692
03693
03694
03695
03696 void TBufferFile::SetGlobalReadParam(Int_t mapsize)
03697 {
03698
03699
03700
03701
03702
03703
03704
03705
03706 fgMapSize = mapsize;
03707 }
03708
03709
03710 void TBufferFile::SetGlobalWriteParam(Int_t mapsize)
03711 {
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721 fgMapSize = mapsize;
03722 }
03723
03724
03725 Int_t TBufferFile::GetGlobalReadParam()
03726 {
03727
03728
03729 return fgMapSize;
03730 }
03731
03732
03733 Int_t TBufferFile::GetGlobalWriteParam()
03734 {
03735
03736
03737 return fgMapSize;
03738 }