00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TBuffer.h"
00013 #include "TClass.h"
00014 #include "TClonesArray.h"
00015 #include "TError.h"
00016 #include "TProcessID.h"
00017 #include "TStreamer.h"
00018 #include "TStreamerElement.h"
00019 #include "TStreamerInfo.h"
00020 #include "TVirtualCollectionProxy.h"
00021 #include "TRefTable.h"
00022 #include "TFile.h"
00023
00024 #include "TVirtualArray.h"
00025 #include "TBufferFile.h"
00026 #include "TInterpreter.h"
00027
00028
00029
00030 #define DOLOOP for(int k=0; k<narr; ++k)
00031
00032 #define WriteBasicTypeElem(name,index) \
00033 { \
00034 name *x=(name*)(arr[index]+ioffset); \
00035 b << *x; \
00036 }
00037
00038 #define WriteBasicType(name) \
00039 { \
00040 WriteBasicTypeElem(name,0); \
00041 }
00042
00043 #define WriteBasicTypeLoop(name) \
00044 { \
00045 for(int k=0; k<narr; ++k) WriteBasicTypeElem(name,k); \
00046 }
00047
00048 #define WriteBasicArrayElem(name,index) \
00049 { \
00050 name *x=(name*)(arr[index]+ioffset); \
00051 b.WriteFastArray(x,fLength[i]); \
00052 }
00053
00054 #define WriteBasicArray(name) \
00055 { \
00056 WriteBasicArrayElem(name,0); \
00057 }
00058
00059 #define WriteBasicArrayLoop(name) \
00060 { \
00061 for(int k=0; k<narr; ++k) WriteBasicArrayElem(name,k); \
00062 }
00063
00064 #define WriteBasicPointerElem(name,index) \
00065 { \
00066 Int_t *l = (Int_t*)(arr[index]+imethod); \
00067 name **f = (name**)(arr[index]+ioffset); \
00068 name *af = *f; \
00069 if (af && *l) b << Char_t(1); \
00070 else {b << Char_t(0); continue;} \
00071 int j; \
00072 for(j=0;j<fLength[i];j++) { \
00073 b.WriteFastArray(f[j],*l); \
00074 } \
00075 }
00076
00077 #define WriteBasicPointer(name) \
00078 { \
00079 int imethod = fMethod[i]+eoffset; \
00080 WriteBasicPointerElem(name,0); \
00081 }
00082
00083 #define WriteBasicPointerLoop(name) \
00084 { \
00085 int imethod = fMethod[i]+eoffset; \
00086 for(int k=0; k<narr; ++k) { \
00087 WriteBasicPointerElem(name,k); \
00088 } \
00089 }
00090
00091
00092 namespace {
00093 template <class T> Bool_t R__TestUseCache(TStreamerElement *element)
00094 {
00095 return element->TestBit(TStreamerElement::kCache);
00096 }
00097
00098 template <> Bool_t R__TestUseCache<TVirtualArray>(TStreamerElement*)
00099 {
00100
00101 return kFALSE;
00102 }
00103 }
00104
00105
00106 #ifdef R__BROKEN_FUNCTION_TEMPLATES
00107 template <class T>
00108 Int_t TStreamerInfo__WriteBufferAuxImp(TStreamerInfo *thisVar,
00109 TBuffer &b, const T &arr, Int_t first,
00110 Int_t narr, Int_t eoffset, Int_t arrayMode,
00111 ULong_t *fMethod, ULong_t *fElem,Int_t *fLength,
00112 TClass *fClass, Int_t *fOffset, Int_t * ,
00113 Int_t fNdata, Int_t *fType, TStreamerElement *& ,
00114 TStreamerInfo::TCompInfo *fComp)
00115 {
00116
00117
00118
00119
00120
00121
00122 #else
00123 template <class T>
00124 Int_t TStreamerInfo::WriteBufferAux(TBuffer &b, const T &arr, Int_t first,
00125 Int_t narr, Int_t eoffset, Int_t arrayMode)
00126 {
00127
00128
00129
00130
00131
00132
00133
00134 TStreamerInfo *thisVar = this;
00135 #endif
00136
00137 b.IncrementLevel(thisVar);
00138
00139
00140 b.TagStreamerInfo(thisVar);
00141
00142
00143
00144
00145 Int_t last;
00146 if (first < 0) {first = 0; last = fNdata;}
00147 else last = first+1;
00148
00149
00150
00151
00152 static const int kHaveLoop = 1024;
00153 const Int_t typeOffset = arrayMode ? kHaveLoop : 0;
00154
00155 for (Int_t i=first;i<last;i++) {
00156
00157 b.SetStreamerElementNumber(i);
00158 TStreamerElement *aElement = (TStreamerElement*)fElem[i];
00159
00160 Int_t ioffset = eoffset+fOffset[i];
00161
00162 if (R__TestUseCache<T>(aElement)) {
00163 if (aElement->TestBit(TStreamerElement::kWrite)) {
00164 if (((TBufferFile&)b).PeekDataCache()==0) {
00165 Warning("WriteBuffer","Skipping %s::%s because the cache is missing.",thisVar->GetName(),aElement->GetName());
00166 } else {
00167 if (gDebug > 1) {
00168 printf("WriteBuffer, class:%s, name=%s, fType[%d]=%d,"
00169 " %s, bufpos=%d, arr=%p, eoffset=%d, Redirect=%p\n",
00170 fClass->GetName(),aElement->GetName(),i,fType[i],
00171 aElement->ClassName(),b.Length(),arr[0], eoffset,((TBufferFile&)b).PeekDataCache()->GetObjectAt(0));
00172 }
00173 thisVar->WriteBufferAux(b,*((TBufferFile&)b).PeekDataCache(),i,narr,eoffset, arrayMode);
00174 }
00175 continue;
00176 } else {
00177 if (gDebug > 1) {
00178 printf("WriteBuffer, class:%s, name=%s, fType[%d]=%d,"
00179 " %s, bufpos=%d, arr=%p, eoffset=%d, not a write rule, skipping.\n",
00180 fClass->GetName(),aElement->GetName(),i,fType[i],
00181 aElement->ClassName(),b.Length(),arr[0], eoffset);
00182 }
00183
00184
00185 if (aElement->TestBit(TStreamerElement::kRepeat)) continue;
00186 ioffset = eoffset+fOffset[i];
00187 }
00188 }
00189
00190
00191 if (gDebug > 1) {
00192 printf("WriteBuffer, class:%s, name=%s, fType[%d]=%d, %s, "
00193 "bufpos=%d, arr=%p, offset=%d\n",
00194 fClass->GetName(),aElement->GetName(),i,fType[i],aElement->ClassName(),
00195 b.Length(),arr[0],ioffset);
00196 }
00197
00198 switch (fType[i]+typeOffset) {
00199
00200
00201
00202
00203 case TStreamerInfo::kBool: WriteBasicType(Bool_t); continue;
00204 case TStreamerInfo::kChar: WriteBasicType(Char_t); continue;
00205 case TStreamerInfo::kShort: WriteBasicType(Short_t); continue;
00206 case TStreamerInfo::kInt: WriteBasicType(Int_t); continue;
00207 case TStreamerInfo::kLong: WriteBasicType(Long_t); continue;
00208 case TStreamerInfo::kLong64: WriteBasicType(Long64_t); continue;
00209 case TStreamerInfo::kFloat: WriteBasicType(Float_t); continue;
00210 case TStreamerInfo::kDouble: WriteBasicType(Double_t); continue;
00211 case TStreamerInfo::kUChar: WriteBasicType(UChar_t); continue;
00212 case TStreamerInfo::kUShort: WriteBasicType(UShort_t); continue;
00213 case TStreamerInfo::kUInt: WriteBasicType(UInt_t); continue;
00214 case TStreamerInfo::kULong: WriteBasicType(ULong_t); continue;
00215 case TStreamerInfo::kULong64: WriteBasicType(ULong64_t); continue;
00216 case TStreamerInfo::kFloat16: {
00217 Float_t *x=(Float_t*)(arr[0]+ioffset);
00218 b.WriteFloat16(x,aElement);
00219 continue;
00220 }
00221 case TStreamerInfo::kDouble32: {
00222 Double_t *x=(Double_t*)(arr[0]+ioffset);
00223 b.WriteDouble32(x,aElement);
00224 continue;
00225 }
00226
00227 case TStreamerInfo::kBool + kHaveLoop: WriteBasicTypeLoop(Bool_t); continue;
00228 case TStreamerInfo::kChar + kHaveLoop: WriteBasicTypeLoop(Char_t); continue;
00229 case TStreamerInfo::kShort + kHaveLoop: WriteBasicTypeLoop(Short_t); continue;
00230 case TStreamerInfo::kInt + kHaveLoop: WriteBasicTypeLoop(Int_t); continue;
00231 case TStreamerInfo::kLong + kHaveLoop: WriteBasicTypeLoop(Long_t); continue;
00232 case TStreamerInfo::kLong64 + kHaveLoop: WriteBasicTypeLoop(Long64_t); continue;
00233 case TStreamerInfo::kFloat + kHaveLoop: WriteBasicTypeLoop(Float_t); continue;
00234 case TStreamerInfo::kDouble + kHaveLoop: WriteBasicTypeLoop(Double_t); continue;
00235 case TStreamerInfo::kUChar + kHaveLoop: WriteBasicTypeLoop(UChar_t); continue;
00236 case TStreamerInfo::kUShort + kHaveLoop: WriteBasicTypeLoop(UShort_t); continue;
00237 case TStreamerInfo::kUInt + kHaveLoop: WriteBasicTypeLoop(UInt_t); continue;
00238 case TStreamerInfo::kULong + kHaveLoop: WriteBasicTypeLoop(ULong_t); continue;
00239 case TStreamerInfo::kULong64 + kHaveLoop: WriteBasicTypeLoop(ULong64_t); continue;
00240 case TStreamerInfo::kFloat16+ kHaveLoop: {
00241 for(int k=0; k<narr; ++k) {
00242 Float_t *x=(Float_t*)(arr[k]+ioffset);
00243 b.WriteFloat16(x,aElement);
00244 }
00245 continue;
00246 }
00247 case TStreamerInfo::kDouble32+ kHaveLoop: {
00248 for(int k=0; k<narr; ++k) {
00249 Double_t *x=(Double_t*)(arr[k]+ioffset);
00250 b.WriteDouble32(x,aElement);
00251 }
00252 continue;
00253 }
00254
00255
00256 case TStreamerInfo::kOffsetL + TStreamerInfo::kBool: WriteBasicArray(Bool_t); continue;
00257 case TStreamerInfo::kOffsetL + TStreamerInfo::kChar: WriteBasicArray(Char_t); continue;
00258 case TStreamerInfo::kOffsetL + TStreamerInfo::kShort: WriteBasicArray(Short_t); continue;
00259 case TStreamerInfo::kOffsetL + TStreamerInfo::kInt: WriteBasicArray(Int_t); continue;
00260 case TStreamerInfo::kOffsetL + TStreamerInfo::kLong: WriteBasicArray(Long_t); continue;
00261 case TStreamerInfo::kOffsetL + TStreamerInfo::kLong64: WriteBasicArray(Long64_t); continue;
00262 case TStreamerInfo::kOffsetL + TStreamerInfo::kFloat: WriteBasicArray(Float_t); continue;
00263 case TStreamerInfo::kOffsetL + TStreamerInfo::kDouble: WriteBasicArray(Double_t); continue;
00264 case TStreamerInfo::kOffsetL + TStreamerInfo::kUChar: WriteBasicArray(UChar_t); continue;
00265 case TStreamerInfo::kOffsetL + TStreamerInfo::kUShort: WriteBasicArray(UShort_t); continue;
00266 case TStreamerInfo::kOffsetL + TStreamerInfo::kUInt: WriteBasicArray(UInt_t); continue;
00267 case TStreamerInfo::kOffsetL + TStreamerInfo::kULong: WriteBasicArray(ULong_t); continue;
00268 case TStreamerInfo::kOffsetL + TStreamerInfo::kULong64:WriteBasicArray(ULong64_t); continue;
00269 case TStreamerInfo::kOffsetL + TStreamerInfo::kFloat16: {
00270 b.WriteFastArrayFloat16((Float_t*)(arr[0]+ioffset),fLength[i],aElement);
00271 continue;
00272 }
00273 case TStreamerInfo::kOffsetL + TStreamerInfo::kDouble32: {
00274 b.WriteFastArrayDouble32((Double_t*)(arr[0]+ioffset),fLength[i],aElement);
00275 continue;
00276 }
00277
00278 case TStreamerInfo::kOffsetL + TStreamerInfo::kBool + kHaveLoop: WriteBasicArrayLoop(Bool_t); continue;
00279 case TStreamerInfo::kOffsetL + TStreamerInfo::kChar + kHaveLoop: WriteBasicArrayLoop(Char_t); continue;
00280 case TStreamerInfo::kOffsetL + TStreamerInfo::kShort + kHaveLoop: WriteBasicArrayLoop(Short_t); continue;
00281 case TStreamerInfo::kOffsetL + TStreamerInfo::kInt + kHaveLoop: WriteBasicArrayLoop(Int_t); continue;
00282 case TStreamerInfo::kOffsetL + TStreamerInfo::kLong + kHaveLoop: WriteBasicArrayLoop(Long_t); continue;
00283 case TStreamerInfo::kOffsetL + TStreamerInfo::kLong64 + kHaveLoop: WriteBasicArrayLoop(Long64_t); continue;
00284 case TStreamerInfo::kOffsetL + TStreamerInfo::kFloat + kHaveLoop: WriteBasicArrayLoop(Float_t); continue;
00285 case TStreamerInfo::kOffsetL + TStreamerInfo::kDouble + kHaveLoop: WriteBasicArrayLoop(Double_t); continue;
00286 case TStreamerInfo::kOffsetL + TStreamerInfo::kUChar + kHaveLoop: WriteBasicArrayLoop(UChar_t); continue;
00287 case TStreamerInfo::kOffsetL + TStreamerInfo::kUShort + kHaveLoop: WriteBasicArrayLoop(UShort_t); continue;
00288 case TStreamerInfo::kOffsetL + TStreamerInfo::kUInt + kHaveLoop: WriteBasicArrayLoop(UInt_t); continue;
00289 case TStreamerInfo::kOffsetL + TStreamerInfo::kULong + kHaveLoop: WriteBasicArrayLoop(ULong_t); continue;
00290 case TStreamerInfo::kOffsetL + TStreamerInfo::kULong64 + kHaveLoop: WriteBasicArrayLoop(ULong64_t); continue;
00291 case TStreamerInfo::kOffsetL + TStreamerInfo::kFloat16+ kHaveLoop: {
00292 for(int k=0; k<narr; ++k) {
00293 b.WriteFastArrayFloat16((Float_t*)(arr[k]+ioffset),fLength[i],aElement);
00294 }
00295 continue;
00296 }
00297 case TStreamerInfo::kOffsetL + TStreamerInfo::kDouble32+ kHaveLoop: {
00298 for(int k=0; k<narr; ++k) {
00299 b.WriteFastArrayDouble32((Double_t*)(arr[k]+ioffset),fLength[i],aElement);
00300 }
00301 continue;
00302 }
00303
00304
00305 case TStreamerInfo::kOffsetP + TStreamerInfo::kBool: WriteBasicPointer(Bool_t); continue;
00306 case TStreamerInfo::kOffsetP + TStreamerInfo::kChar: WriteBasicPointer(Char_t); continue;
00307 case TStreamerInfo::kOffsetP + TStreamerInfo::kShort: WriteBasicPointer(Short_t); continue;
00308 case TStreamerInfo::kOffsetP + TStreamerInfo::kInt: WriteBasicPointer(Int_t); continue;
00309 case TStreamerInfo::kOffsetP + TStreamerInfo::kLong: WriteBasicPointer(Long_t); continue;
00310 case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: WriteBasicPointer(Long64_t); continue;
00311 case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat: WriteBasicPointer(Float_t); continue;
00312 case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: WriteBasicPointer(Double_t); continue;
00313 case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar: WriteBasicPointer(UChar_t); continue;
00314 case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: WriteBasicPointer(UShort_t); continue;
00315 case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt: WriteBasicPointer(UInt_t); continue;
00316 case TStreamerInfo::kOffsetP + TStreamerInfo::kULong: WriteBasicPointer(ULong_t); continue;
00317 case TStreamerInfo::kOffsetP + TStreamerInfo::kULong64:WriteBasicPointer(ULong64_t); continue;
00318 case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat16: {
00319 int imethod = fMethod[i]+eoffset;
00320 Int_t *l = (Int_t*)(arr[0]+imethod);
00321 Float_t **f = (Float_t**)(arr[0]+ioffset);
00322 Float_t *af = *f;
00323 if (af && *l) b << Char_t(1);
00324 else {b << Char_t(0); continue;}
00325 int j;
00326 for(j=0;j<fLength[i];j++) {
00327 b.WriteFastArrayFloat16(f[j],*l,aElement);
00328 }
00329 continue;
00330 }
00331 case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble32: {
00332 int imethod = fMethod[i]+eoffset;
00333 Int_t *l = (Int_t*)(arr[0]+imethod);
00334 Double_t **f = (Double_t**)(arr[0]+ioffset);
00335 Double_t *af = *f;
00336 if (af && *l) b << Char_t(1);
00337 else {b << Char_t(0); continue;}
00338 int j;
00339 for(j=0;j<fLength[i];j++) {
00340 b.WriteFastArrayDouble32(f[j],*l,aElement);
00341 }
00342 continue;
00343 }
00344
00345 case TStreamerInfo::kOffsetP + TStreamerInfo::kBool + kHaveLoop: WriteBasicPointerLoop(Bool_t); continue;
00346 case TStreamerInfo::kOffsetP + TStreamerInfo::kChar + kHaveLoop: WriteBasicPointerLoop(Char_t); continue;
00347 case TStreamerInfo::kOffsetP + TStreamerInfo::kShort + kHaveLoop: WriteBasicPointerLoop(Short_t); continue;
00348 case TStreamerInfo::kOffsetP + TStreamerInfo::kInt + kHaveLoop: WriteBasicPointerLoop(Int_t); continue;
00349 case TStreamerInfo::kOffsetP + TStreamerInfo::kLong + kHaveLoop: WriteBasicPointerLoop(Long_t); continue;
00350 case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64 + kHaveLoop: WriteBasicPointerLoop(Long64_t); continue;
00351 case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat + kHaveLoop: WriteBasicPointerLoop(Float_t); continue;
00352 case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble + kHaveLoop: WriteBasicPointerLoop(Double_t); continue;
00353 case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar + kHaveLoop: WriteBasicPointerLoop(UChar_t); continue;
00354 case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort + kHaveLoop: WriteBasicPointerLoop(UShort_t); continue;
00355 case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt + kHaveLoop: WriteBasicPointerLoop(UInt_t); continue;
00356 case TStreamerInfo::kOffsetP + TStreamerInfo::kULong + kHaveLoop: WriteBasicPointerLoop(ULong_t); continue;
00357 case TStreamerInfo::kOffsetP + TStreamerInfo::kULong64 + kHaveLoop: WriteBasicPointerLoop(ULong64_t); continue;
00358 case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat16+ kHaveLoop: {
00359 int imethod = fMethod[i]+eoffset;
00360 for(int k=0; k<narr; ++k) {
00361 Int_t *l = (Int_t*)(arr[k]+imethod);
00362 Float_t **f = (Float_t**)(arr[k]+ioffset);
00363 Float_t *af = *f;
00364 if (af && *l) b << Char_t(1);
00365 else {b << Char_t(0); continue;}
00366 int j;
00367 for(j=0;j<fLength[i];j++) {
00368 b.WriteFastArrayFloat16(f[j],*l,aElement);
00369 }
00370 }
00371 continue;
00372 }
00373 case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble32+ kHaveLoop: {
00374 int imethod = fMethod[i]+eoffset;
00375 for(int k=0; k<narr; ++k) {
00376 Int_t *l = (Int_t*)(arr[k]+imethod);
00377 Double_t **f = (Double_t**)(arr[k]+ioffset);
00378 Double_t *af = *f;
00379 if (af && *l) b << Char_t(1);
00380 else {b << Char_t(0); continue;}
00381 int j;
00382 for(j=0;j<fLength[i];j++) {
00383 b.WriteFastArrayDouble32(f[j],*l,aElement);
00384 }
00385 }
00386 continue;
00387 }
00388
00389 case TStreamerInfo::kCounter: {
00390 Int_t *x=(Int_t*)(arr[0]+ioffset);
00391 b << *x;
00392 if (i == last-1) {
00393 b.DecrementLevel(thisVar);
00394 return x[0];
00395 }
00396 continue;
00397 }
00398
00399 case TStreamerInfo::kCounter + kHaveLoop : {
00400 DOLOOP {
00401 Int_t *x=(Int_t*)(arr[k]+ioffset);
00402 b << x[0];
00403 }
00404 continue;
00405 }
00406
00407
00408 };
00409 Bool_t isPreAlloc = 0;
00410
00411 switch (fType[i]) {
00412
00413
00414 case TStreamerInfo::kCharStar: { DOLOOP {
00415 Int_t nch = 0;
00416 char **f = (char**)(arr[k]+ioffset);
00417 char *af = *f;
00418 if (af) {
00419 nch = strlen(af);
00420 b << nch;
00421 b.WriteFastArray(af,nch);
00422 } else {
00423 b << nch;
00424 }
00425 }
00426 continue; }
00427
00428
00429 case TStreamerInfo::kBits: { DOLOOP {
00430 UInt_t *x=(UInt_t*)(arr[k]+ioffset); b << *x;
00431 if ((*x & kIsReferenced) != 0) {
00432 TObject *obj = (TObject*)(arr[k]+eoffset);
00433 TProcessID *pid = TProcessID::GetProcessWithUID(obj->GetUniqueID(),obj);
00434 TRefTable *table = TRefTable::GetRefTable();
00435 if(table) table->Add(obj->GetUniqueID(),pid);
00436 UShort_t pidf = b.WriteProcessID(pid);
00437 b << pidf;
00438 }
00439 }
00440 continue; }
00441
00442
00443 case TStreamerInfo::kTString: { DOLOOP{ ((TString*)(arr[k]+ioffset))->Streamer(b); }; continue; }
00444 case TStreamerInfo::kTObject: { DOLOOP{ ((TObject*)(arr[k]+ioffset))->TObject::Streamer(b);}; continue; }
00445 case TStreamerInfo::kTNamed: { DOLOOP{ ((TNamed *)(arr[k]+ioffset))->TNamed::Streamer(b); }; continue; }
00446
00447 case TStreamerInfo::kAnyp:
00448 case TStreamerInfo::kAnyp + TStreamerInfo::kOffsetL:
00449
00450 case TStreamerInfo::kObjectp:
00451 case TStreamerInfo::kObjectp + TStreamerInfo::kOffsetL:
00452
00453 isPreAlloc = kTRUE;
00454
00455
00456 case TStreamerInfo::kAnyP:
00457 case TStreamerInfo::kAnyP + TStreamerInfo::kOffsetL:
00458
00459 case TStreamerInfo::kObjectP:
00460 case TStreamerInfo::kObjectP + TStreamerInfo::kOffsetL: {
00461 TClass *cl = fComp[i].fClass;
00462 TMemberStreamer *pstreamer = fComp[i].fStreamer;
00463 DOLOOP {
00464 Int_t res = b.WriteFastArray((void**)(arr[k]+ioffset),cl,fLength[i],isPreAlloc,pstreamer);
00465 if (res==2) {
00466 Warning("WriteBuffer",
00467 "The actual class of %s::%s is not available. Only the \"%s\" part will be written\n",
00468 thisVar->GetName(),aElement->GetName(),cl->GetName());
00469 }
00470 }
00471 continue;
00472 }
00473
00474 case TStreamerInfo::kAnyPnoVT:
00475 case TStreamerInfo::kAnyPnoVT + TStreamerInfo::kOffsetL: {
00476 TClass *cl = fComp[i].fClass;
00477 TMemberStreamer *pstreamer = fComp[i].fStreamer;
00478 DOLOOP {
00479 void **f = (void**)(arr[k]+ioffset);
00480 int j;
00481 for(j=0;j<fLength[i];j++) {
00482 void *af = f[j];
00483 if (af) b << Char_t(1);
00484 else {b << Char_t(0); continue;}
00485 if (pstreamer) (*pstreamer)(b, af, 0);
00486 else cl->Streamer( af, b );
00487 }
00488 }
00489 continue;
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 case TStreamerInfo::kSTLp:
00522 case TStreamerInfo::kSTLp + TStreamerInfo::kOffsetL:
00523 {
00524 TClass *cl = fComp[i].fClass;
00525 TMemberStreamer *pstreamer = fComp[i].fStreamer;
00526 TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
00527 TClass* vClass = proxy ? proxy->GetValueClass() : 0;
00528
00529 if (!b.TestBit(TBuffer::kCannotHandleMemberWiseStreaming)
00530 && proxy && vClass
00531 && thisVar->GetStreamMemberWise()
00532 && cl->CanSplit()
00533 && !(strspn(aElement->GetTitle(),"||") == 2)
00534 && !(gInterpreter->ClassInfo_RootFlag(vClass->GetClassInfo()) & 1) ) {
00535
00536
00537 UInt_t pos = b.WriteVersionMemberWise(thisVar->IsA(),kTRUE);
00538 b.WriteVersion( vClass, kFALSE );
00539 TStreamerInfo *subinfo = (TStreamerInfo*)vClass->GetStreamerInfo();
00540 if (subinfo->IsOptimized()) {
00541 subinfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
00542 subinfo->Compile();
00543 }
00544 DOLOOP {
00545 char **contp = (char**)(arr[k]+ioffset);
00546 for(int j=0;j<fLength[i];++j) {
00547 char *cont = contp[j];
00548 TVirtualCollectionProxy::TPushPop helper( proxy, cont );
00549 Int_t nobjects = cont ? proxy->Size() : 0;
00550 b << nobjects;
00551 subinfo->WriteBufferSTL(b,proxy,nobjects,-1,0);
00552 }
00553 }
00554 b.SetByteCount(pos,kTRUE);
00555 continue;
00556 }
00557 UInt_t pos = b.WriteVersion(thisVar->IsA(),kTRUE);
00558 if (pstreamer == 0) {
00559 DOLOOP {
00560 char **contp = (char**)(arr[k]+ioffset);
00561 for(int j=0;j<fLength[i];++j) {
00562 char *cont = contp[j];
00563 cl->Streamer( cont, b );
00564 }
00565 }
00566 } else {
00567 DOLOOP{(*pstreamer)(b,arr[k]+ioffset,fLength[i]);}
00568 }
00569 b.SetByteCount(pos,kTRUE);
00570 }
00571 continue;
00572
00573 case TStreamerInfo::kSTL:
00574 case TStreamerInfo::kSTL + TStreamerInfo::kOffsetL:
00575 {
00576 TClass *cl = fComp[i].fClass;
00577 TMemberStreamer *pstreamer = fComp[i].fStreamer;
00578 TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
00579 TClass* vClass = proxy ? proxy->GetValueClass() : 0;
00580 if (!b.TestBit(TBuffer::kCannotHandleMemberWiseStreaming)
00581 && proxy && vClass
00582 && thisVar->GetStreamMemberWise() && cl->CanSplit()
00583 && !(strspn(aElement->GetTitle(),"||") == 2)
00584 && !(vClass->GetClassInfo() && (gInterpreter->ClassInfo_RootFlag(vClass->GetClassInfo()) & 1) ) ) {
00585
00586
00587 UInt_t pos = b.WriteVersionMemberWise(thisVar->IsA(),kTRUE);
00588 b.WriteVersion( vClass, kFALSE );
00589 TStreamerInfo *subinfo = (TStreamerInfo*)vClass->GetStreamerInfo();
00590 if (subinfo->IsOptimized()) {
00591 subinfo->SetBit(TVirtualStreamerInfo::kCannotOptimize);
00592 subinfo->Compile();
00593 }
00594 DOLOOP {
00595 char *obj = (char*)(arr[k]+ioffset);
00596 Int_t n = fLength[i];
00597 if (!n) n=1;
00598 int size = cl->Size();
00599
00600 for(Int_t j=0; j<n; j++,obj+=size) {
00601 TVirtualCollectionProxy::TPushPop helper( proxy, obj );
00602 Int_t nobjects = proxy->Size();
00603 b << nobjects;
00604 subinfo->WriteBufferSTL(b,proxy,nobjects,-1,0);
00605 }
00606 }
00607 b.SetByteCount(pos,kTRUE);
00608 continue;
00609 }
00610 UInt_t pos = b.WriteVersion(thisVar->IsA(),kTRUE);
00611 if (pstreamer == 0) {
00612 DOLOOP {
00613 b.WriteFastArray((void*)(arr[k]+ioffset),cl,fLength[i],0);
00614 }
00615 } else {
00616 DOLOOP{(*pstreamer)(b,arr[k]+ioffset,fLength[i]);}
00617 }
00618 b.SetByteCount(pos,kTRUE);
00619
00620 continue;
00621 }
00622
00623 case TStreamerInfo::kObject:
00624 case TStreamerInfo::kAny:
00625 case TStreamerInfo::kOffsetL + TStreamerInfo::kObject:
00626 case TStreamerInfo::kAny + TStreamerInfo::kOffsetL: {
00627 TClass *cl = fComp[i].fClass;
00628 TMemberStreamer *pstreamer = fComp[i].fStreamer;
00629 DOLOOP
00630 {b.WriteFastArray((void*)(arr[k]+ioffset),cl,fLength[i],pstreamer);}
00631 continue;
00632 }
00633
00634 case TStreamerInfo::kOffsetL + TStreamerInfo::kTString:
00635 case TStreamerInfo::kOffsetL + TStreamerInfo::kTObject:
00636 case TStreamerInfo::kOffsetL + TStreamerInfo::kTNamed:
00637 {
00638 TMemberStreamer *pstreamer = fComp[i].fStreamer;
00639 TClass *cl = fComp[i].fClass;
00640
00641 UInt_t pos = b.WriteVersion(thisVar->IsA(),kTRUE);
00642 DOLOOP {b.WriteFastArray((void*)(arr[k]+ioffset),cl,fLength[i],pstreamer);}
00643 b.SetByteCount(pos,kTRUE);
00644 continue;
00645 }
00646
00647
00648 case TStreamerInfo::kBase:
00649 if (!(arrayMode&1)) {
00650 TMemberStreamer *pstreamer = fComp[i].fStreamer;
00651 if(pstreamer) {
00652
00653 UInt_t pos = b.WriteVersion(thisVar->IsA(),kTRUE);
00654 DOLOOP{(*pstreamer)(b,arr[k]+ioffset,fLength[i]);}
00655 b.SetByteCount(pos,kTRUE);
00656 } else {
00657 DOLOOP { ((TStreamerBase*)aElement)->WriteBuffer(b,arr[k]);}
00658 }
00659 } else {
00660 TClass *cl = fComp[i].fClass;
00661 TStreamerInfo *binfo = ((TStreamerInfo*)cl->GetStreamerInfo());
00662 if (!binfo->TestBit(kCannotOptimize) && binfo->IsCompiled()) {
00663 binfo->SetBit(kCannotOptimize);
00664 binfo->Compile();
00665 }
00666 binfo->WriteBufferAux(b,arr,-1,narr,ioffset,arrayMode);
00667 }
00668 continue;
00669
00670 case TStreamerInfo::kStreamer:
00671 {
00672 TMemberStreamer *pstreamer = fComp[i].fStreamer;
00673
00674 UInt_t pos = b.WriteVersion(thisVar->IsA(),kTRUE);
00675 if (pstreamer == 0) {
00676 printf("ERROR, Streamer is null\n");
00677 aElement->ls();continue;
00678 } else {
00679 DOLOOP{(*pstreamer)(b,arr[k]+ioffset,fLength[i]);}
00680 }
00681 b.SetByteCount(pos,kTRUE);
00682 }
00683 continue;
00684
00685 case TStreamerInfo::kStreamLoop:
00686
00687
00688
00689
00690 case TStreamerInfo::kOffsetL + TStreamerInfo::kStreamLoop:
00691
00692
00693
00694
00695 {
00696
00697 TClass* cl = fComp[i].fClass;
00698
00699 TMemberStreamer* pstreamer = fComp[i].fStreamer;
00700
00701 Bool_t isPtrPtr = (strstr(aElement->GetTypeName(), "**") != 0);
00702 if (pstreamer) {
00703
00704 UInt_t pos = b.WriteVersion(thisVar->IsA(), kTRUE);
00705
00706 for (int k = 0; k < narr; ++k) {
00707
00708 Int_t* counter = (Int_t*) (arr[k] + eoffset + fMethod[i] );
00709
00710 (*pstreamer)(b, arr[k] + ioffset , *counter);
00711 }
00712 b.SetByteCount(pos, kTRUE);
00713
00714 continue;
00715 }
00716
00717
00718 TFile* file = (TFile*) b.GetParent();
00719
00720 Int_t fileVersion = kMaxInt;
00721 if (file) {
00722 fileVersion = file->GetVersion();
00723 }
00724
00725 UInt_t pos = b.WriteVersion(thisVar->IsA(), kTRUE);
00726 if (fileVersion > 51508) {
00727
00728
00729 for (int k = 0; k < narr; ++k) {
00730
00731 Int_t vlen = *((Int_t*) (arr[k] + eoffset + fMethod[i] ));
00732
00733 if (vlen) {
00734
00735 char** pp = (char**) (arr[k] + ioffset );
00736
00737 for (Int_t ndx = 0; ndx < fLength[i]; ++ndx) {
00738 if (!pp[ndx]) {
00739
00740 Error("WriteBufferAux", "The pointer to element %s::%s type %d (%s) is null\n", thisVar->GetName(), aElement->GetFullName(), fType[i], aElement->GetTypeName());
00741 continue;
00742 }
00743 if (!isPtrPtr) {
00744
00745
00746
00747 b.WriteFastArray(pp[ndx], cl, vlen, 0);
00748 }
00749 else {
00750
00751
00752
00753 b.WriteFastArray((void**) pp[ndx], cl, vlen, kFALSE, 0);
00754 }
00755 }
00756 }
00757 }
00758 }
00759 else {
00760
00761
00762 for (int k = 0; k < narr; ++k) {
00763
00764 Int_t vlen = *((Int_t*) (arr[k] + eoffset + fMethod[i] ));
00765
00766 if (vlen) {
00767
00768 char** pp = (char**) (arr[k] + ioffset );
00769
00770
00771 for (Int_t ndx = 0; ndx < fLength[i]; ++ndx) {
00772 if (!pp[ndx]) {
00773
00774 Error("WriteBufferAux", "The pointer to element %s::%s type %d (%s) is null\n", thisVar->GetName(), aElement->GetFullName(), fType[i], aElement->GetTypeName());
00775 continue;
00776 }
00777 if (!isPtrPtr) {
00778
00779
00780 for (Int_t v = 0; v < vlen; ++v) {
00781
00782 cl->Streamer(pp[ndx] + (v * cl->Size()), b);
00783 }
00784 }
00785 else {
00786
00787
00788 for (Int_t v = 0; v < vlen; ++v) {
00789
00790 char** r = (char**) pp[ndx];
00791
00792 cl->Streamer(r[v], b);
00793 }
00794 }
00795 }
00796 }
00797 }
00798 }
00799
00800 b.SetByteCount(pos, kTRUE);
00801 continue;
00802 }
00803
00804 case TStreamerInfo::kCacheNew:
00805 ((TBufferFile&)b).PushDataCache( new TVirtualArray( aElement->GetClassPointer(), narr ) );
00806 continue;
00807 case TStreamerInfo::kCacheDelete:
00808 delete ((TBufferFile&)b).PopDataCache();
00809 continue;
00810 case TStreamerInfo::kArtificial:
00811 #if 0
00812 ROOT::TSchemaRule::WriteFuncPtr_t writefunc = ((TStreamerArtificialElement*)aElement)->GetWriteFunc();
00813 if (writefunc) {
00814 DOLOOP( writefunc(arr[k]+eoffset, b) );
00815 }
00816 #endif
00817 continue;
00818 default:
00819 Error("WriteBuffer","The element %s::%s type %d (%s) is not supported yet\n",thisVar->GetName(),aElement->GetFullName(),fType[i],aElement->GetTypeName());
00820 continue;
00821 }
00822 }
00823
00824 b.DecrementLevel(thisVar);
00825
00826 return 0;
00827 }
00828
00829 #ifdef R__BROKEN_FUNCTION_TEMPLATES
00830
00831
00832 Int_t TStreamerInfo::WriteBufferAux(TBuffer &b, char ** const &arr, Int_t first,Int_t narr,Int_t eoffset,Int_t mode)
00833 {
00834 return TStreamerInfo__WriteBufferAuxImp(this,b,arr,first,narr,eoffset,mode,
00835 fMethod,fElem,fLength,fClass,fOffset,fNewType,
00836 fNdata,fType,fgElement,fComp);
00837 }
00838
00839 Int_t TStreamerInfo::WriteBufferAux(TBuffer &b, const TVirtualCollectionProxy &arr, Int_t first,Int_t narr,Int_t eoffset,Int_t mode)
00840 {
00841 return TStreamerInfo__WriteBufferAuxImp(this,b,arr,first,narr,eoffset,mode,
00842 fMethod,fElem,fLength,fClass,fOffset,fNewType,
00843 fNdata,fType,fgElement,fComp);
00844 }
00845
00846 Int_t TStreamerInfo::WriteBufferAux(TBuffer &b, const TPointerCollectionAdapter &arr, Int_t first,Int_t narr,Int_t eoffset,Int_t mode)
00847 {
00848 return TStreamerInfo__WriteBufferAuxImp(this,b,arr,first,narr,eoffset,mode,
00849 fMethod,fElem,fLength,fClass,fOffset,fNewType,
00850 fNdata,fType,fgElement,fComp);
00851 }
00852
00853 Int_t TStreamerInfo::WriteBufferAux(TBuffer &b, const TVirtualArray &arr, Int_t first,Int_t narr,Int_t eoffset,Int_t mode)
00854 {
00855 return TStreamerInfo__WriteBufferAuxImp(this,b,arr,first,narr,eoffset,mode,
00856 fMethod,fElem,fLength,fClass,fOffset,fNewType,
00857 fNdata,fType,fgElement,fComp);
00858 }
00859
00860 #endif
00861
00862
00863 Int_t TStreamerInfo::WriteBufferSTL(TBuffer &b, TVirtualCollectionProxy *cont, Int_t nc, Int_t first, Int_t eoffset)
00864 {
00865
00866
00867 if (!nc) return 0;
00868 R__ASSERT((unsigned int)nc==cont->Size());
00869
00870 int ret = WriteBufferAux(b, *cont,first,nc,eoffset,1);
00871 return ret;
00872 }
00873
00874
00875 Int_t TStreamerInfo::WriteBufferSTLPtrs(TBuffer &b, TVirtualCollectionProxy *cont, Int_t nc, Int_t first, Int_t eoffset )
00876 {
00877
00878 if (!nc) return 0;
00879 R__ASSERT((unsigned int)nc==cont->Size());
00880 int ret = WriteBufferAux(b, TPointerCollectionAdapter(cont),first,nc,eoffset,1);
00881 return ret;
00882 }
00883
00884
00885
00886 Int_t TStreamerInfo::WriteBuffer(TBuffer &b, char *ipointer, Int_t first)
00887 {
00888
00889
00890 return WriteBufferAux(b,&ipointer,first,1,0,0);
00891 }
00892
00893
00894 Int_t TStreamerInfo::WriteBufferClones(TBuffer &b, TClonesArray *clones,
00895 Int_t nc, Int_t first, Int_t eoffset)
00896 {
00897
00898
00899 char **arr = reinterpret_cast<char**>(clones->GetObjectRef(0));
00900 return WriteBufferAux(b,arr,first,nc,eoffset,1);
00901 }
00902
00903