00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "TEmulatedCollectionProxy.h"
00027 #include "TStreamerElement.h"
00028 #include "TStreamerInfo.h"
00029 #include "TClassEdit.h"
00030 #include "TError.h"
00031 #include "TROOT.h"
00032 #include "Riostream.h"
00033
00034 #include "TVirtualMutex.h"
00035
00036
00037
00038
00039
00040
00041 static TStreamerElement* R__CreateEmulatedElement(const char *dmName, const char *dmFull, Int_t offset);
00042 static TStreamerInfo *R__GenerateTClassForPair(const string &f, const string &s);
00043
00044 TEmulatedCollectionProxy::TEmulatedCollectionProxy(const TEmulatedCollectionProxy& copy)
00045 : TGenCollectionProxy(copy)
00046 {
00047
00048 fProperties |= kIsEmulated;
00049 }
00050
00051 TEmulatedCollectionProxy::TEmulatedCollectionProxy(const char* cl_name)
00052 : TGenCollectionProxy(typeid(std::vector<char>), sizeof(std::vector<char>::iterator))
00053 {
00054
00055
00056 fName = cl_name;
00057 if ( this->TEmulatedCollectionProxy::InitializeEx() ) {
00058 fCreateEnv = TGenCollectionProxy::Env_t::Create;
00059 }
00060 fProperties |= kIsEmulated;
00061 }
00062
00063 TEmulatedCollectionProxy::~TEmulatedCollectionProxy()
00064 {
00065
00066 if ( fEnv && fEnv->fObject ) {
00067 Clear();
00068 }
00069 }
00070
00071 TVirtualCollectionProxy* TEmulatedCollectionProxy::Generate() const
00072 {
00073
00074
00075 if ( !fClass ) Initialize();
00076 return new TEmulatedCollectionProxy(*this);
00077 }
00078
00079 void TEmulatedCollectionProxy::Destructor(void* p, Bool_t dtorOnly)
00080 {
00081
00082
00083 if (!p) return;
00084 if (!fEnv || fEnv->fObject != p) {
00085 TVirtualCollectionProxy::TPushPop env(this, p);
00086 Clear("force");
00087 } else {
00088 Clear("force");
00089 }
00090 if (dtorOnly) {
00091 ((Cont_t*)p)->~Cont_t();
00092 } else {
00093 delete (Cont_t*) p;
00094 }
00095 }
00096
00097 void TEmulatedCollectionProxy::DeleteArray(void* p, Bool_t dtorOnly)
00098 {
00099
00100
00101
00102
00103 Warning("DeleteArray", "Cannot properly delete emulated array of %s at %p, I don't know how many elements it has!", fClass->GetName(), p);
00104 if (!dtorOnly) {
00105 delete[] (Cont_t*) p;
00106 }
00107 }
00108
00109 TGenCollectionProxy *TEmulatedCollectionProxy::InitializeEx()
00110 {
00111
00112 R__LOCKGUARD2(gCollectionMutex);
00113 if (fClass) return this;
00114
00115
00116 TClass *cl = TClass::GetClass(fName.c_str());
00117 fEnv = 0;
00118 fKey = 0;
00119 if ( cl ) {
00120 int nested = 0;
00121 std::vector<std::string> inside;
00122 fPointers = false;
00123 int num = TClassEdit::GetSplit(fName.c_str(),inside,nested);
00124 if ( num > 1 ) {
00125 std::string nam;
00126 if ( inside[0].find("stdext::hash_") != std::string::npos ) {
00127 inside[0].replace(3,10,"::");
00128 }
00129 if ( inside[0].find("__gnu_cxx::hash_") != std::string::npos ) {
00130 inside[0].replace(0,16,"std::");
00131 }
00132 fSTL_type = TClassEdit::STLKind(inside[0].c_str());
00133
00134
00135
00136
00137 int slong = sizeof(void*);
00138 switch ( fSTL_type ) {
00139 case TClassEdit::kMap:
00140 case TClassEdit::kMultiMap:
00141 nam = "pair<"+inside[1]+","+inside[2];
00142 nam += (nam[nam.length()-1]=='>') ? " >" : ">";
00143 if (0==TClass::GetClass(nam.c_str())) {
00144
00145 R__GenerateTClassForPair(inside[1],inside[2]);
00146 }
00147 fValue = new Value(nam);
00148 fKey = new Value(inside[1]);
00149 fVal = new Value(inside[2]);
00150 if ( !fValue->IsValid() || !fKey->IsValid() || !fVal->IsValid() ) {
00151 return 0;
00152 }
00153 fPointers |= 0 != (fKey->fCase&G__BIT_ISPOINTER);
00154 if ( 0 == fValDiff ) {
00155 fValDiff = fKey->fSize + fVal->fSize;
00156 fValDiff += (slong - fKey->fSize%slong)%slong;
00157 fValDiff += (slong - fValDiff%slong)%slong;
00158 }
00159 if ( 0 == fValOffset ) {
00160 fValOffset = fKey->fSize;
00161 fValOffset += (slong - fKey->fSize%slong)%slong;
00162 }
00163 break;
00164 case TClassEdit::kBitSet:
00165 inside[1] = "bool";
00166
00167 default:
00168 fValue = new Value(inside[1]);
00169 fVal = new Value(*fValue);
00170 if ( !fValue->IsValid() || !fVal->IsValid() ) {
00171 return 0;
00172 }
00173 if ( 0 == fValDiff ) {
00174 fValDiff = fVal->fSize;
00175 if (fVal->fCase != G__BIT_ISFUNDAMENTAL) {
00176 fValDiff += (slong - fValDiff%slong)%slong;
00177 }
00178 }
00179 break;
00180 }
00181 fPointers |= 0 != (fVal->fCase&G__BIT_ISPOINTER);
00182 fClass = cl;
00183 return this;
00184 }
00185 Fatal("TEmulatedCollectionProxy","Components of %s not analysed!",cl->GetName());
00186 }
00187 Fatal("TEmulatedCollectionProxy","Collection class %s not found!",fTypeinfo.name());
00188 return 0;
00189 }
00190
00191 Bool_t TEmulatedCollectionProxy::IsValid() const
00192 {
00193
00194 return (0 != fCreateEnv.call);
00195 }
00196
00197 UInt_t TEmulatedCollectionProxy::Size() const
00198 {
00199
00200
00201 if ( fEnv && fEnv->fObject ) {
00202 return fEnv->fSize = PCont_t(fEnv->fObject)->size()/fValDiff;
00203 }
00204 Fatal("TEmulatedCollectionProxy","Size> Logic error - no proxy object set.");
00205 return 0;
00206 }
00207
00208 void TEmulatedCollectionProxy::Clear(const char* opt)
00209 {
00210
00211 Resize(0, opt && *opt=='f');
00212 }
00213
00214 void TEmulatedCollectionProxy::Shrink(UInt_t nCurr, UInt_t left, Bool_t force )
00215 {
00216
00217
00218 typedef std::string String_t;
00219 PCont_t c = PCont_t(fEnv->fObject);
00220 char* addr = ((char*)fEnv->fStart) + fValDiff*left;
00221 size_t i;
00222
00223 switch ( fSTL_type ) {
00224 case TClassEdit::kMap:
00225 case TClassEdit::kMultiMap:
00226 addr = ((char*)fEnv->fStart) + fValDiff*left;
00227 switch(fKey->fCase) {
00228 case G__BIT_ISFUNDAMENTAL:
00229 case G__BIT_ISENUM:
00230 break;
00231 case G__BIT_ISCLASS:
00232 for( i= fKey->fType ? left : nCurr; i<nCurr; ++i, addr += fValDiff ) {
00233
00234 fKey->fType->Destructor(addr, kTRUE);
00235 }
00236 break;
00237 case kBIT_ISSTRING:
00238 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
00239 ((std::string*)addr)->~String_t();
00240 }
00241 break;
00242 case G__BIT_ISPOINTER|G__BIT_ISCLASS:
00243 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
00244 StreamHelper* h = (StreamHelper*)addr;
00245
00246
00247 void* ptr = h->ptr();
00248 if (force) fKey->fType->Destructor(ptr);
00249 h->set(0);
00250 }
00251 break;
00252 case G__BIT_ISPOINTER|kBIT_ISSTRING:
00253 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
00254 StreamHelper* h = (StreamHelper*)addr;
00255
00256
00257 if (force) delete (std::string*)h->ptr();
00258 h->set(0);
00259 }
00260 break;
00261 case G__BIT_ISPOINTER|kBIT_ISTSTRING|G__BIT_ISCLASS:
00262 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
00263 StreamHelper* h = (StreamHelper*)addr;
00264 if (force) delete (TString*)h->ptr();
00265 h->set(0);
00266 }
00267 break;
00268 }
00269 addr = ((char*)fEnv->fStart)+fValOffset+fValDiff*left;
00270
00271
00272
00273 default:
00274 switch( fVal->fCase ) {
00275 case G__BIT_ISFUNDAMENTAL:
00276 case G__BIT_ISENUM:
00277 break;
00278 case G__BIT_ISCLASS:
00279 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
00280
00281 fVal->fType->Destructor(addr,kTRUE);
00282 }
00283 break;
00284 case kBIT_ISSTRING:
00285 for( i=left; i<nCurr; ++i, addr += fValDiff )
00286 ((std::string*)addr)->~String_t();
00287 break;
00288 case G__BIT_ISPOINTER|G__BIT_ISCLASS:
00289 for( i=left; i<nCurr; ++i, addr += fValDiff ) {
00290 StreamHelper* h = (StreamHelper*)addr;
00291 void* p = h->ptr();
00292 if ( p && force ) {
00293 fVal->fType->Destructor(p);
00294 }
00295 h->set(0);
00296 }
00297 break;
00298 case G__BIT_ISPOINTER|kBIT_ISSTRING:
00299 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
00300 StreamHelper* h = (StreamHelper*)addr;
00301 if (force) delete (std::string*)h->ptr();
00302 h->set(0);
00303 }
00304 break;
00305 case G__BIT_ISPOINTER|kBIT_ISTSTRING|G__BIT_ISCLASS:
00306 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
00307 StreamHelper* h = (StreamHelper*)addr;
00308 if (force) delete (TString*)h->ptr();
00309 h->set(0);
00310 }
00311 break;
00312 }
00313 }
00314 c->resize(left*fValDiff,0);
00315 fEnv->fStart = left>0 ? &(*c->begin()) : 0;
00316 return;
00317 }
00318
00319 void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left)
00320 {
00321
00322 size_t i;
00323 PCont_t c = PCont_t(fEnv->fObject);
00324 c->resize(left*fValDiff,0);
00325 void *oldstart = fEnv->fStart;
00326 fEnv->fStart = left>0 ? &(*c->begin()) : 0;
00327
00328 char* addr = ((char*)fEnv->fStart) + fValDiff*nCurr;
00329 switch ( fSTL_type ) {
00330 case TClassEdit::kMap:
00331 case TClassEdit::kMultiMap:
00332 switch(fKey->fCase) {
00333 case G__BIT_ISFUNDAMENTAL:
00334 case G__BIT_ISENUM:
00335 break;
00336 case G__BIT_ISCLASS:
00337 if (oldstart && oldstart != fEnv->fStart) {
00338 Long_t offset = 0;
00339 for( i=0; i<=nCurr; ++i, offset += fValDiff ) {
00340
00341
00342
00343 fKey->fType->Move(((char*)oldstart)+offset,((char*)fEnv->fStart)+offset);
00344 }
00345 }
00346 for( i=nCurr; i<left; ++i, addr += fValDiff )
00347 fKey->fType->New(addr);
00348 break;
00349 case kBIT_ISSTRING:
00350 for( i=nCurr; i<left; ++i, addr += fValDiff )
00351 ::new(addr) std::string();
00352 break;
00353 case G__BIT_ISPOINTER|G__BIT_ISCLASS:
00354 case G__BIT_ISPOINTER|kBIT_ISSTRING:
00355 case G__BIT_ISPOINTER|kBIT_ISTSTRING|G__BIT_ISCLASS:
00356 for( i=nCurr; i<left; ++i, addr += fValDiff )
00357 *(void**)addr = 0;
00358 break;
00359 }
00360 addr = ((char*)fEnv->fStart)+fValOffset+fValDiff*nCurr;
00361
00362
00363
00364 default:
00365 switch(fVal->fCase) {
00366 case G__BIT_ISFUNDAMENTAL:
00367 case G__BIT_ISENUM:
00368 break;
00369 case G__BIT_ISCLASS:
00370 if (oldstart && oldstart != fEnv->fStart) {
00371 Long_t offset = 0;
00372 for( i=0; i<=nCurr; ++i, offset += fValDiff ) {
00373
00374
00375
00376 fVal->fType->Move(((char*)oldstart)+offset,((char*)fEnv->fStart)+offset);
00377 }
00378 }
00379 for( i=nCurr; i<left; ++i, addr += fValDiff ) {
00380 fVal->fType->New(addr);
00381 }
00382 break;
00383 case kBIT_ISSTRING:
00384 for( i=nCurr; i<left; ++i, addr += fValDiff )
00385 ::new(addr) std::string();
00386 break;
00387 case G__BIT_ISPOINTER|G__BIT_ISCLASS:
00388 case G__BIT_ISPOINTER|kBIT_ISSTRING:
00389 case G__BIT_ISPOINTER|kBIT_ISTSTRING|G__BIT_ISCLASS:
00390 for( i=nCurr; i<left; ++i, addr += fValDiff )
00391 *(void**)addr = 0;
00392 break;
00393 }
00394 break;
00395 }
00396 }
00397
00398 void TEmulatedCollectionProxy::Resize(UInt_t left, Bool_t force)
00399 {
00400
00401
00402 if ( fEnv && fEnv->fObject ) {
00403 size_t nCurr = Size();
00404 PCont_t c = PCont_t(fEnv->fObject);
00405 fEnv->fStart = nCurr>0 ? &(*c->begin()) : 0;
00406 if ( left == nCurr ) {
00407 return;
00408 }
00409 else if ( left < nCurr ) {
00410 Shrink(nCurr, left, force);
00411 return;
00412 }
00413 Expand(nCurr, left);
00414 return;
00415 }
00416 Fatal("TEmulatedCollectionProxy","Resize> Logic error - no proxy object set.");
00417 }
00418
00419 void* TEmulatedCollectionProxy::At(UInt_t idx)
00420 {
00421
00422 if ( fEnv && fEnv->fObject ) {
00423 PCont_t c = PCont_t(fEnv->fObject);
00424 size_t s = c->size();
00425 if ( idx >= (s/fValDiff) ) {
00426 return 0;
00427 }
00428 return idx<(s/fValDiff) ? ((char*)&(*c->begin()))+idx*fValDiff : 0;
00429 }
00430 Fatal("TEmulatedCollectionProxy","At> Logic error - no proxy object set.");
00431 return 0;
00432 }
00433
00434 void* TEmulatedCollectionProxy::Allocate(UInt_t n, Bool_t forceDelete)
00435 {
00436
00437
00438 Resize(n, forceDelete);
00439 return fEnv->fObject;
00440 }
00441
00442 void TEmulatedCollectionProxy::Commit(void* )
00443 {
00444 }
00445
00446 void TEmulatedCollectionProxy::ReadItems(int nElements, TBuffer &b)
00447 {
00448
00449 Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
00450 StreamHelper* itm = (StreamHelper*)At(0);
00451 switch (fVal->fCase) {
00452 case G__BIT_ISFUNDAMENTAL:
00453 case G__BIT_ISENUM:
00454 switch( int(fVal->fKind) ) {
00455 case kBool_t: b.ReadFastArray(&itm->boolean , nElements); break;
00456 case kChar_t: b.ReadFastArray(&itm->s_char , nElements); break;
00457 case kShort_t: b.ReadFastArray(&itm->s_short , nElements); break;
00458 case kInt_t: b.ReadFastArray(&itm->s_int , nElements); break;
00459 case kLong_t: b.ReadFastArray(&itm->s_long , nElements); break;
00460 case kLong64_t: b.ReadFastArray(&itm->s_longlong, nElements); break;
00461 case kFloat_t: b.ReadFastArray(&itm->flt , nElements); break;
00462 case kFloat16_t: b.ReadFastArrayFloat16(&itm->flt, nElements); break;
00463 case kDouble_t: b.ReadFastArray(&itm->dbl , nElements); break;
00464 case kBOOL_t: b.ReadFastArray(&itm->boolean , nElements); break;
00465 case kUChar_t: b.ReadFastArray(&itm->u_char , nElements); break;
00466 case kUShort_t: b.ReadFastArray(&itm->u_short , nElements); break;
00467 case kUInt_t: b.ReadFastArray(&itm->u_int , nElements); break;
00468 case kULong_t: b.ReadFastArray(&itm->u_long , nElements); break;
00469 case kULong64_t: b.ReadFastArray(&itm->u_longlong, nElements); break;
00470 case kDouble32_t:b.ReadFastArrayDouble32(&itm->dbl,nElements); break;
00471 case kchar:
00472 case kNoType_t:
00473 case kOther_t:
00474 Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
00475 }
00476 break;
00477
00478 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
00479
00480 case G__BIT_ISCLASS:
00481 DOLOOP( b.StreamObject(i,fVal->fType) );
00482 case kBIT_ISSTRING:
00483 DOLOOP( i->read_std_string(b) );
00484 case G__BIT_ISPOINTER|G__BIT_ISCLASS:
00485 DOLOOP( i->read_any_object(fVal,b) );
00486 case G__BIT_ISPOINTER|kBIT_ISSTRING:
00487 DOLOOP( i->read_std_string_pointer(b) );
00488 case G__BIT_ISPOINTER|kBIT_ISTSTRING|G__BIT_ISCLASS:
00489 DOLOOP( i->read_tstring_pointer(vsn3,b) );
00490 }
00491
00492 #undef DOLOOP
00493
00494 }
00495
00496 void TEmulatedCollectionProxy::WriteItems(int nElements, TBuffer &b)
00497 {
00498
00499 StreamHelper* itm = (StreamHelper*)At(0);
00500 switch (fVal->fCase) {
00501 case G__BIT_ISFUNDAMENTAL:
00502 case G__BIT_ISENUM:
00503 itm = (StreamHelper*)At(0);
00504 switch( int(fVal->fKind) ) {
00505 case kBool_t: b.WriteFastArray(&itm->boolean , nElements); break;
00506 case kChar_t: b.WriteFastArray(&itm->s_char , nElements); break;
00507 case kShort_t: b.WriteFastArray(&itm->s_short , nElements); break;
00508 case kInt_t: b.WriteFastArray(&itm->s_int , nElements); break;
00509 case kLong_t: b.WriteFastArray(&itm->s_long , nElements); break;
00510 case kLong64_t: b.WriteFastArray(&itm->s_longlong, nElements); break;
00511 case kFloat_t: b.WriteFastArray(&itm->flt , nElements); break;
00512 case kFloat16_t: b.WriteFastArrayFloat16(&itm->flt, nElements); break;
00513 case kDouble_t: b.WriteFastArray(&itm->dbl , nElements); break;
00514 case kBOOL_t: b.WriteFastArray(&itm->boolean , nElements); break;
00515 case kUChar_t: b.WriteFastArray(&itm->u_char , nElements); break;
00516 case kUShort_t: b.WriteFastArray(&itm->u_short , nElements); break;
00517 case kUInt_t: b.WriteFastArray(&itm->u_int , nElements); break;
00518 case kULong_t: b.WriteFastArray(&itm->u_long , nElements); break;
00519 case kULong64_t: b.WriteFastArray(&itm->u_longlong, nElements); break;
00520 case kDouble32_t:b.WriteFastArrayDouble32(&itm->dbl,nElements); break;
00521 case kchar:
00522 case kNoType_t:
00523 case kOther_t:
00524 Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
00525 }
00526 break;
00527 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
00528 case G__BIT_ISCLASS:
00529 DOLOOP( b.StreamObject(i,fVal->fType) );
00530 case kBIT_ISSTRING:
00531 DOLOOP( TString(i->c_str()).Streamer(b) );
00532 case G__BIT_ISPOINTER|G__BIT_ISCLASS:
00533 DOLOOP( b.WriteObjectAny(i->ptr(),fVal->fType) );
00534 case kBIT_ISSTRING|G__BIT_ISPOINTER:
00535 DOLOOP( i->write_std_string_pointer(b) );
00536 case kBIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
00537 DOLOOP( i->write_tstring_pointer(b) );
00538 }
00539 #undef DOLOOP
00540 }
00541
00542 void TEmulatedCollectionProxy::ReadBuffer(TBuffer &b, void *obj, const TClass *onfileClass)
00543 {
00544
00545
00546 SetOnFileClass((TClass*)onfileClass);
00547 ReadBuffer(b,obj);
00548 }
00549
00550 void TEmulatedCollectionProxy::ReadBuffer(TBuffer &b, void *obj)
00551 {
00552
00553
00554 TPushPop env(this,obj);
00555 int nElements = 0;
00556 b >> nElements;
00557 if ( fEnv->fObject ) {
00558 Resize(nElements,true);
00559 }
00560 if ( nElements > 0 ) {
00561 ReadItems(nElements, b);
00562 }
00563 }
00564
00565 void TEmulatedCollectionProxy::Streamer(TBuffer &b)
00566 {
00567
00568 if ( b.IsReading() ) {
00569 int nElements = 0;
00570 b >> nElements;
00571 if ( fEnv->fObject ) {
00572 Resize(nElements,true);
00573 }
00574 if ( nElements > 0 ) {
00575 ReadItems(nElements, b);
00576 }
00577 }
00578 else {
00579 int nElements = fEnv->fObject ? Size() : 0;
00580 b << nElements;
00581 if ( nElements > 0 ) {
00582 WriteItems(nElements, b);
00583 }
00584 }
00585 }
00586
00587
00588
00589
00590 static TStreamerElement* R__CreateEmulatedElement(const char *dmName, const char *dmFull, Int_t offset)
00591 {
00592
00593
00594 TString s1( TClassEdit::ShortType(dmFull,0) );
00595 TString dmType( TClassEdit::ShortType(dmFull,1) );
00596 bool dmIsPtr = (s1 != dmType);
00597 const char *dmTitle = "Emulation";
00598
00599 TDataType *dt = gROOT->GetType(dmType);
00600 if (dt && dt->GetType() > 0 ) {
00601 Int_t dsize,dtype;
00602 dtype = dt->GetType();
00603 dsize = dt->Size();
00604 if (dmIsPtr && dtype != kCharStar) {
00605 Error("Pair Emulation Building","%s is not yet supported in pair emulation",
00606 dmFull);
00607 return 0;
00608 } else {
00609 TStreamerElement *el = new TStreamerBasicType(dmName,dmTitle,offset,dtype,dmFull);
00610 el->SetSize(dsize);
00611 return el;
00612 }
00613 } else {
00614
00615 static const char *full_string_name = "basic_string<char,char_traits<char>,allocator<char> >";
00616 if (strcmp(dmType,"string") == 0 || strcmp(dmType,full_string_name)==0 ) {
00617 return new TStreamerSTLstring(dmName,dmTitle,offset,dmFull,dmIsPtr);
00618 }
00619 if (TClassEdit::IsSTLCont(dmType)) {
00620 return new TStreamerSTL(dmName,dmTitle,offset,dmFull,dmFull,dmIsPtr);
00621 }
00622 TClass *clm = TClass::GetClass(dmType);
00623 if (!clm) {
00624
00625
00626 Int_t dtype = kInt_t;
00627 return new TStreamerBasicType(dmName,dmTitle,offset,dtype,dmFull);
00628 }
00629
00630 if ( dmIsPtr ) {
00631 if (clm->InheritsFrom(TObject::Class())) {
00632 return new TStreamerObjectPointer(dmName,dmTitle,offset,dmFull);
00633 } else {
00634 return new TStreamerObjectAnyPointer(dmName,dmTitle,offset,dmFull);
00635 }
00636 }
00637
00638 if (clm->InheritsFrom(TObject::Class())) {
00639 return new TStreamerObject(dmName,dmTitle,offset,dmFull);
00640 } else if(clm == TString::Class() && !dmIsPtr) {
00641 return new TStreamerString(dmName,dmTitle,offset);
00642 } else {
00643 return new TStreamerObjectAny(dmName,dmTitle,offset,dmFull);
00644 }
00645 }
00646 }
00647
00648
00649 static TStreamerInfo *R__GenerateTClassForPair(const string &fname, const string &sname)
00650 {
00651
00652
00653
00654
00655 TStreamerInfo *i = (TStreamerInfo*)TClass::GetClass("pair<const int,int>")->GetStreamerInfo()->Clone();
00656 std::string pname = "pair<"+fname+","+sname;
00657 pname += (pname[pname.length()-1]=='>') ? " >" : ">";
00658 i->SetName(pname.c_str());
00659 i->SetClass(0);
00660 i->GetElements()->Delete();
00661 TStreamerElement *fel = R__CreateEmulatedElement("first", fname.c_str(), 0);
00662 Int_t size = 0;
00663 if (fel) {
00664 i->GetElements()->Add( fel );
00665
00666 size = fel->GetSize();
00667 Int_t sp = sizeof(void *);
00668 #if defined(R__SGI64)
00669 sp = 8;
00670 #endif
00671
00672 if (size%sp != 0) size = size - size%sp + sp;
00673 } else {
00674 delete i;
00675 return 0;
00676 }
00677 TStreamerElement *second = R__CreateEmulatedElement("second", sname.c_str(), size);
00678 if (second) {
00679 i->GetElements()->Add( second );
00680 } else {
00681 delete i;
00682 return 0;
00683 }
00684 Int_t oldlevel = gErrorIgnoreLevel;
00685
00686 gErrorIgnoreLevel = kError;
00687 i->BuildCheck();
00688 gErrorIgnoreLevel = oldlevel;
00689 i->BuildOld();
00690 return i;
00691 }