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 "TGenCollectionProxy.h"
00027 #include "TVirtualStreamerInfo.h"
00028 #include "TStreamerElement.h"
00029 #include "TClassEdit.h"
00030 #include "TClass.h"
00031 #include "TError.h"
00032 #include "TROOT.h"
00033 #include "TInterpreter.h"
00034 #include "Riostream.h"
00035 #include "TVirtualMutex.h"
00036 #include "TStreamerInfoActions.h"
00037 #include <stdlib.h>
00038
00039 #define MESSAGE(which,text)
00040
00041 std::vector<TVirtualCollectionProxy*> gSlowIterator__Proxy;
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 class TGenVectorProxy : public TGenCollectionProxy {
00055 public:
00056
00057 TGenVectorProxy(const TGenCollectionProxy& c) : TGenCollectionProxy(c)
00058 {
00059 }
00060
00061 virtual ~TGenVectorProxy()
00062 {
00063 }
00064
00065 virtual void* At(UInt_t idx)
00066 {
00067 if ( fEnv && fEnv->fObject ) {
00068 fEnv->fIdx = idx;
00069 switch( idx ) {
00070 case 0:
00071 return fEnv->fStart = fFirst.invoke(fEnv);
00072 default:
00073 if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00074 return ((char*)fEnv->fStart) + fValDiff*idx;
00075 }
00076 }
00077 Fatal("TGenVectorProxy","At> Logic error - no proxy object set.");
00078 return 0;
00079 }
00080
00081 virtual void DeleteItem(bool force, void* ptr) const
00082 {
00083 if ( force && ptr ) {
00084 fVal->DeleteItem(ptr);
00085 }
00086 }
00087 };
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 class TGenVectorBoolProxy : public TGenCollectionProxy {
00101 bool fLastValue;
00102
00103 public:
00104 TGenVectorBoolProxy(const TGenCollectionProxy& c) : TGenCollectionProxy(c), fLastValue(false)
00105 {
00106
00107 }
00108 virtual ~TGenVectorBoolProxy()
00109 {
00110
00111 }
00112 virtual void* At(UInt_t idx)
00113 {
00114
00115
00116
00117 if ( fEnv && fEnv->fObject ) {
00118 switch( idx ) {
00119 case 0:
00120 fEnv->fStart = fFirst.invoke(fEnv);
00121 fEnv->fIdx = idx;
00122 break;
00123 default:
00124 fEnv->fIdx = idx - fEnv->fIdx;
00125 if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00126 fNext.invoke(fEnv);
00127 fEnv->fIdx = idx;
00128 break;
00129 }
00130 typedef ROOT::TCollectionProxyInfo::Type<std::vector<bool> >::Env_t EnvType_t;
00131 EnvType_t *e = (EnvType_t*)fEnv;
00132 fLastValue = *(e->iter());
00133 return &fLastValue;
00134 }
00135 Fatal("TGenVectorProxy","At> Logic error - no proxy object set.");
00136 return 0;
00137 }
00138
00139 virtual void DeleteItem(bool force, void* ptr) const
00140 {
00141
00142 if ( force && ptr ) {
00143 fVal->DeleteItem(ptr);
00144 }
00145 }
00146 };
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 class TGenBitsetProxy : public TGenCollectionProxy {
00160
00161 public:
00162 TGenBitsetProxy(const TGenCollectionProxy& c) : TGenCollectionProxy(c)
00163 {
00164
00165 }
00166 virtual ~TGenBitsetProxy()
00167 {
00168
00169 }
00170 virtual void* At(UInt_t idx)
00171 {
00172
00173
00174
00175 if ( fEnv && fEnv->fObject ) {
00176 switch( idx ) {
00177 case 0:
00178 fEnv->fStart = fFirst.invoke(fEnv);
00179 fEnv->fIdx = idx;
00180 break;
00181 default:
00182 fEnv->fIdx = idx - fEnv->fIdx;
00183 if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00184 fNext.invoke(fEnv);
00185 fEnv->fIdx = idx;
00186 break;
00187 }
00188 typedef ROOT::TCollectionProxyInfo::Environ<std::pair<size_t,bool> > EnvType_t;
00189 EnvType_t *e = (EnvType_t*)fEnv;
00190 return &(e->fIterator.second);
00191 }
00192 Fatal("TGenVectorProxy","At> Logic error - no proxy object set.");
00193 return 0;
00194 }
00195
00196 virtual void DeleteItem(bool force, void* ptr) const
00197 {
00198
00199 if ( force && ptr ) {
00200 fVal->DeleteItem(ptr);
00201 }
00202 }
00203 };
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 class TGenListProxy : public TGenVectorProxy {
00217 public:
00218
00219 TGenListProxy(const TGenCollectionProxy& c) : TGenVectorProxy(c)
00220 {
00221 }
00222
00223 virtual ~TGenListProxy()
00224 {
00225 }
00226
00227 void* At(UInt_t idx)
00228 {
00229 if ( fEnv && fEnv->fObject ) {
00230 switch( idx ) {
00231 case 0:
00232 fEnv->fIdx = idx;
00233 return fEnv->fStart = fFirst.invoke(fEnv);
00234 default: {
00235 fEnv->fIdx = idx - fEnv->fIdx;
00236 if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00237 void* result = fNext.invoke(fEnv);
00238 fEnv->fIdx = idx;
00239 return result;
00240 }
00241 }
00242 }
00243 Fatal("TGenListProxy","At> Logic error - no proxy object set.");
00244 return 0;
00245 }
00246 };
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 class TGenSetProxy : public TGenVectorProxy {
00260 public:
00261
00262 TGenSetProxy(const TGenCollectionProxy& c) : TGenVectorProxy(c)
00263 {
00264 }
00265
00266 virtual ~TGenSetProxy()
00267 {
00268 }
00269
00270 void* At(UInt_t idx)
00271 {
00272 if ( fEnv && fEnv->fObject ) {
00273 if ( fEnv->fUseTemp ) {
00274 return (((char*)fEnv->fTemp)+idx*fValDiff);
00275 }
00276 switch( idx ) {
00277 case 0:
00278 fEnv->fIdx = idx;
00279 return fEnv->fStart = fFirst.invoke(fEnv);
00280 default: {
00281 fEnv->fIdx = idx - fEnv->fIdx;
00282 if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00283 void* result = fNext.invoke(fEnv);
00284 fEnv->fIdx = idx;
00285 return result;
00286 }
00287 }
00288 }
00289 Fatal("TGenSetProxy","At> Logic error - no proxy object set.");
00290 return 0;
00291 }
00292 };
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 class TGenMapProxy : public TGenSetProxy {
00306 public:
00307
00308 TGenMapProxy(const TGenCollectionProxy& c) : TGenSetProxy(c)
00309 {
00310 }
00311
00312 virtual ~TGenMapProxy()
00313 {
00314 }
00315
00316 virtual void DeleteItem(Bool_t , void* ptr) const
00317 {
00318 if ( fKey->fCase&G__BIT_ISPOINTER ) {
00319 fKey->DeleteItem(*(void**)ptr);
00320 }
00321 if ( fVal->fCase&G__BIT_ISPOINTER ) {
00322 char *addr = ((char*)ptr)+fValOffset;
00323 fVal->DeleteItem(*(void**)addr);
00324 }
00325 }
00326 };
00327
00328
00329
00330 TGenCollectionProxy::Value::Value(const Value& copy)
00331 {
00332
00333
00334 fType = copy.fType;
00335 fCase = copy.fCase;
00336 fKind = copy.fKind;
00337 fSize = copy.fSize;
00338 fCtor = copy.fCtor;
00339 fDtor = copy.fDtor;
00340 fDelete = copy.fDelete;
00341 }
00342
00343
00344 TGenCollectionProxy::Value::Value(const std::string& inside_type)
00345 {
00346
00347
00348 std::string inside = (inside_type.find("const ")==0) ? inside_type.substr(6) : inside_type;
00349 fCase = 0;
00350 fCtor = 0;
00351 fDtor = 0;
00352 fDelete = 0;
00353 fSize = std::string::npos;
00354 fKind = kNoType_t;
00355 std::string intype = TClassEdit::ShortType(inside.c_str(),TClassEdit::kDropTrailStar );
00356 if ( inside.substr(0,6) == "string" || inside.substr(0,11) == "std::string" ) {
00357 fCase = kBIT_ISSTRING;
00358 fType = TClass::GetClass("string");
00359 fCtor = fType->GetNew();
00360 fDtor = fType->GetDestructor();
00361 fDelete = fType->GetDelete();
00362 switch(inside[inside.length()-1]) {
00363 case '*':
00364 fCase |= G__BIT_ISPOINTER;
00365 fSize = sizeof(void*);
00366 break;
00367 default:
00368 fSize = sizeof(std::string);
00369 break;
00370 }
00371 }
00372 else {
00373
00374
00375
00376
00377
00378 fType = TClass::GetClass(intype.c_str());
00379 if (fType && !fType->IsLoaded()) {
00380 if (intype != inside) {
00381 fCase |= G__BIT_ISPOINTER;
00382 fSize = sizeof(void*);
00383 }
00384 fCase |= G__BIT_ISCLASS;
00385 fCtor = fType->GetNew();
00386 fDtor = fType->GetDestructor();
00387 fDelete = fType->GetDelete();
00388 } else {
00389 #if defined(NOT_YET)
00390
00391
00392
00393
00394
00395 G__value gval = G__string2type_body(inside.c_str(),2);
00396 G__TypeInfo ti(gval);
00397 #else
00398
00399 TypeInfo_t *ti = gCint->TypeInfo_Factory();
00400 gCint->TypeInfo_Init(ti,inside.c_str());
00401 #endif
00402 if ( !gCint->TypeInfo_IsValid(ti) ) {
00403 if (intype != inside) {
00404 fCase |= G__BIT_ISPOINTER;
00405 fSize = sizeof(void*);
00406 }
00407 fType = TClass::GetClass(intype.c_str());
00408 if (fType) {
00409 fCase |= G__BIT_ISCLASS;
00410 fCtor = fType->GetNew();
00411 fDtor = fType->GetDestructor();
00412 fDelete = fType->GetDelete();
00413 }
00414 else {
00415
00416
00417 fCase = G__BIT_ISENUM;
00418 fSize = sizeof(Int_t);
00419 fKind = kInt_t;
00420 }
00421 }
00422 else {
00423 Long_t prop = gCint->TypeInfo_Property(ti);
00424 if ( prop&G__BIT_ISPOINTER ) {
00425 fSize = sizeof(void*);
00426 }
00427 if ( prop&G__BIT_ISSTRUCT ) {
00428 prop |= G__BIT_ISCLASS;
00429 }
00430 if ( prop&G__BIT_ISCLASS ) {
00431 fType = TClass::GetClass(intype.c_str());
00432 R__ASSERT(fType);
00433 fCtor = fType->GetNew();
00434 fDtor = fType->GetDestructor();
00435 fDelete = fType->GetDelete();
00436 }
00437 else if ( prop&G__BIT_ISFUNDAMENTAL ) {
00438 TDataType *fundType = gROOT->GetType( intype.c_str() );
00439 if (fundType==0) {
00440 if (intype != "long double") {
00441 Error("TGenCollectionProxy","Unknown fundamental type %s",intype.c_str());
00442 }
00443 fSize = sizeof(int);
00444 fKind = kInt_t;
00445 } else {
00446 fKind = (EDataType)fundType->GetType();
00447 if ( 0 == strcmp("bool",fundType->GetFullTypeName()) ) {
00448 fKind = (EDataType)kBOOL_t;
00449 }
00450 fSize = gCint->TypeInfo_Size(ti);
00451 R__ASSERT((fKind>0 && fKind<0x16) || (fKind==-1&&(prop&G__BIT_ISPOINTER)) );
00452 }
00453 }
00454 else if ( prop&G__BIT_ISENUM ) {
00455 fSize = sizeof(int);
00456 fKind = kInt_t;
00457 }
00458 fCase = prop & (G__BIT_ISPOINTER|G__BIT_ISFUNDAMENTAL|G__BIT_ISENUM|G__BIT_ISCLASS);
00459 if (fType == TString::Class() && (fCase&G__BIT_ISPOINTER)) {
00460 fCase |= kBIT_ISTSTRING;
00461 }
00462 }
00463 gCint->TypeInfo_Delete(ti);
00464 }
00465 }
00466 if ( fSize == std::string::npos ) {
00467 if ( fType == 0 ) {
00468
00469 } else {
00470 fSize = fType->Size();
00471 }
00472 }
00473 }
00474
00475 Bool_t TGenCollectionProxy::Value::IsValid()
00476 {
00477
00478
00479 return fSize != std::string::npos;
00480 }
00481
00482 void TGenCollectionProxy::Value::DeleteItem(void* ptr)
00483 {
00484
00485
00486 if ( ptr && fCase&G__BIT_ISPOINTER ) {
00487 if ( fDelete ) {
00488 (*fDelete)(ptr);
00489 }
00490 else if ( fType ) {
00491 fType->Destructor(ptr);
00492 }
00493 else {
00494 ::operator delete(ptr);
00495 }
00496 }
00497 }
00498
00499
00500 TGenCollectionProxy::TGenCollectionProxy(const TGenCollectionProxy& copy)
00501 : TVirtualCollectionProxy(copy.fClass),
00502 fTypeinfo(copy.fTypeinfo)
00503 {
00504
00505 fEnv = 0;
00506 fName = copy.fName;
00507 fPointers = copy.fPointers;
00508 fSTL_type = copy.fSTL_type;
00509 fSize.call = copy.fSize.call;
00510 fNext.call = copy.fNext.call;
00511 fFirst.call = copy.fFirst.call;
00512 fClear.call = copy.fClear.call;
00513 fResize = copy.fResize;
00514 fDestruct = copy.fDestruct;
00515 fConstruct = copy.fConstruct;
00516 fFeed = copy.fFeed;
00517 fCollect.call = copy.fCollect.call;
00518 fCreateEnv.call = copy.fCreateEnv.call;
00519 fValOffset = copy.fValOffset;
00520 fValDiff = copy.fValDiff;
00521 fValue = copy.fValue ? new Value(*copy.fValue) : 0;
00522 fVal = copy.fVal ? new Value(*copy.fVal) : 0;
00523 fKey = copy.fKey ? new Value(*copy.fKey) : 0;
00524 fOnFileClass = copy.fOnFileClass;
00525 fReadMemberWise = new TObjArray(TCollection::kInitCapacity,-1);
00526 fConversionReadMemberWise = 0;
00527 fProperties = copy.fProperties;
00528 fFunctionCreateIterators = copy.fFunctionCreateIterators;
00529 fFunctionDeleteTwoIterators = copy.fFunctionDeleteTwoIterators;
00530 }
00531
00532
00533 TGenCollectionProxy::TGenCollectionProxy(Info_t info, size_t iter_size)
00534 : TVirtualCollectionProxy(0),
00535 fTypeinfo(info)
00536 {
00537
00538 fEnv = 0;
00539 fSize.call = 0;
00540 fFirst.call = 0;
00541 fNext.call = 0;
00542 fClear.call = 0;
00543 fResize = 0;
00544 fDestruct = 0;
00545 fConstruct = 0;
00546 fCollect.call = 0;
00547 fCreateEnv.call = 0;
00548 fFeed = 0;
00549 fValue = 0;
00550 fKey = 0;
00551 fVal = 0;
00552 fValOffset = 0;
00553 fValDiff = 0;
00554 fPointers = false;
00555 fOnFileClass = 0;
00556 fSTL_type = TClassEdit::kNotSTL;
00557 Env_t e;
00558 if ( iter_size > sizeof(e.fIterator) ) {
00559 Fatal("TGenCollectionProxy",
00560 "%s %s are too large:%ld bytes. Maximum is:%ld bytes",
00561 "Iterators for collection",
00562 fClass->GetName(),
00563 (Long_t)iter_size,
00564 (Long_t)sizeof(e.fIterator));
00565 }
00566 fReadMemberWise = new TObjArray(TCollection::kInitCapacity,-1);
00567 fConversionReadMemberWise = 0;
00568 fFunctionCreateIterators = 0;
00569 fFunctionDeleteTwoIterators = 0;
00570 }
00571
00572
00573 TGenCollectionProxy::TGenCollectionProxy(const ROOT::TCollectionProxyInfo &info, TClass *cl)
00574 : TVirtualCollectionProxy(cl),
00575 fTypeinfo(info.fInfo), fOnFileClass(0)
00576 {
00577
00578 fEnv = 0;
00579 fValDiff = info.fValueDiff;
00580 fValOffset = info.fValueOffset;
00581 fSize.call = info.fSizeFunc;
00582 fResize = info.fResizeFunc;
00583 fNext.call = info.fNextFunc;
00584 fFirst.call = info.fFirstFunc;
00585 fClear.call = info.fClearFunc;
00586 fConstruct = info.fConstructFunc;
00587 fDestruct = info.fDestructFunc;
00588 fFeed = info.fFeedFunc;
00589 fCollect.call = info.fCollectFunc;
00590 fCreateEnv.call = info.fCreateEnv;
00591
00592 if (cl) {
00593 fName = cl->GetName();
00594 }
00595 CheckFunctions();
00596
00597 fValue = 0;
00598 fKey = 0;
00599 fVal = 0;
00600 fPointers = false;
00601 fSTL_type = TClassEdit::kNotSTL;
00602
00603 Env_t e;
00604 if ( info.fIterSize > sizeof(e.fIterator) ) {
00605 Fatal("TGenCollectionProxy",
00606 "%s %s are too large:%ld bytes. Maximum is:%ld bytes",
00607 "Iterators for collection",
00608 fClass->GetName(),
00609 (Long_t)info.fIterSize,
00610 (Long_t)sizeof(e.fIterator));
00611 }
00612 fReadMemberWise = new TObjArray(TCollection::kInitCapacity,-1);
00613 fConversionReadMemberWise = 0;
00614 fFunctionCreateIterators = 0;
00615 fFunctionDeleteTwoIterators = 0;
00616 }
00617
00618 namespace {
00619 template <class vec>
00620 void clearVector(vec& v)
00621 {
00622
00623
00624 for(typename vec::iterator i=v.begin(); i != v.end(); ++i) {
00625 typename vec::value_type e = *i;
00626 if ( e ) {
00627 delete e;
00628 }
00629 }
00630 v.clear();
00631 }
00632 }
00633
00634 TGenCollectionProxy::~TGenCollectionProxy()
00635 {
00636
00637 clearVector(fProxyList);
00638 clearVector(fProxyKept);
00639 clearVector(fStaged);
00640
00641 if ( fValue ) delete fValue;
00642 if ( fVal ) delete fVal;
00643 if ( fKey ) delete fKey;
00644
00645 delete fReadMemberWise;
00646 if (fConversionReadMemberWise) {
00647 std::map<std::string, TObjArray*>::iterator it;
00648 std::map<std::string, TObjArray*>::iterator end = fConversionReadMemberWise->end();
00649 for( it = fConversionReadMemberWise->begin(); it != end; ++it ) {
00650 delete it->second;
00651 }
00652 delete fConversionReadMemberWise;
00653 fConversionReadMemberWise = 0;
00654 }
00655 }
00656
00657
00658 TVirtualCollectionProxy* TGenCollectionProxy::Generate() const
00659 {
00660
00661 if ( !fValue ) Initialize();
00662
00663 if( fPointers )
00664 return new TGenCollectionProxy(*this);
00665
00666 switch(fSTL_type) {
00667 case TClassEdit::kBitSet: {
00668 return new TGenBitsetProxy(*this);
00669 }
00670 case TClassEdit::kVector: {
00671 if (fValue->fKind == (EDataType)kBOOL_t) {
00672 return new TGenVectorBoolProxy(*this);
00673 } else {
00674 return new TGenVectorProxy(*this);
00675 }
00676 }
00677 case TClassEdit::kList:
00678 return new TGenListProxy(*this);
00679 case TClassEdit::kMap:
00680 case TClassEdit::kMultiMap:
00681 return new TGenMapProxy(*this);
00682 case TClassEdit::kSet:
00683 case TClassEdit::kMultiSet:
00684 return new TGenSetProxy(*this);
00685 default:
00686 return new TGenCollectionProxy(*this);
00687 }
00688 }
00689
00690
00691 TGenCollectionProxy *TGenCollectionProxy::Initialize() const
00692 {
00693
00694 TGenCollectionProxy* p = const_cast<TGenCollectionProxy*>(this);
00695 if ( fValue ) return p;
00696 const_cast<TGenCollectionProxy*>(this)->fProperties |= kIsInitialized;
00697 return p->InitializeEx();
00698 }
00699
00700
00701 void TGenCollectionProxy::CheckFunctions() const
00702 {
00703
00704 if ( 0 == fSize.call ) {
00705 Fatal("TGenCollectionProxy","No 'size' function pointer for class %s present.",fName.c_str());
00706 }
00707 if ( 0 == fResize ) {
00708 Fatal("TGenCollectionProxy","No 'resize' function for class %s present.",fName.c_str());
00709 }
00710 if ( 0 == fNext.call ) {
00711 Fatal("TGenCollectionProxy","No 'next' function for class %s present.",fName.c_str());
00712 }
00713 if ( 0 == fFirst.call ) {
00714 Fatal("TGenCollectionProxy","No 'begin' function for class %s present.",fName.c_str());
00715 }
00716 if ( 0 == fClear.call ) {
00717 Fatal("TGenCollectionProxy","No 'clear' function for class %s present.",fName.c_str());
00718 }
00719 if ( 0 == fConstruct ) {
00720 Fatal("TGenCollectionProxy","No 'block constructor' function for class %s present.",fName.c_str());
00721 }
00722 if ( 0 == fDestruct ) {
00723 Fatal("TGenCollectionProxy","No 'block destructor' function for class %s present.",fName.c_str());
00724 }
00725 if ( 0 == fFeed ) {
00726 Fatal("TGenCollectionProxy","No 'data feed' function for class %s present.",fName.c_str());
00727 }
00728 if ( 0 == fCollect.call ) {
00729 Fatal("TGenCollectionProxy","No 'data collect' function for class %s present.",fName.c_str());
00730 }
00731 if (0 == fCreateEnv.call ) {
00732 Fatal("TGenCollectionProxy","No 'environment creation' function for class %s present.",fName.c_str());
00733 }
00734 }
00735
00736
00737 static TGenCollectionProxy::Value *R__CreateValue(const std::string &name)
00738 {
00739
00740 TGenCollectionProxy::Value *val = new TGenCollectionProxy::Value( name );
00741 if ( !val->IsValid() ) {
00742 Fatal("TGenCollectionProxy","Could not find %s!",name.c_str());
00743 }
00744 return val;
00745 }
00746
00747
00748 TGenCollectionProxy *TGenCollectionProxy::InitializeEx()
00749 {
00750
00751 R__LOCKGUARD2(gCollectionMutex);
00752 if (fValue) return this;
00753
00754 TClass *cl = fClass ? fClass.GetClass() : TClass::GetClass(fTypeinfo);
00755 if ( cl ) {
00756 fEnv = 0;
00757 fName = cl->GetName();
00758 fPointers = false;
00759 int nested = 0;
00760 std::vector<std::string> inside;
00761 int num = TClassEdit::GetSplit(cl->GetName(),inside,nested);
00762 if ( num > 1 ) {
00763 std::string nam;
00764 if ( inside[0].find("stdext::hash_") != std::string::npos )
00765 inside[0].replace(3,10,"::");
00766 if ( inside[0].find("__gnu_cxx::hash_") != std::string::npos )
00767 inside[0].replace(0,16,"std::");
00768 fSTL_type = TClassEdit::STLKind(inside[0].c_str());
00769 switch ( fSTL_type ) {
00770 case TClassEdit::kMap:
00771 case TClassEdit::kMultiMap:
00772 case TClassEdit::kSet:
00773 case TClassEdit::kMultiSet:
00774 fProperties |= kIsAssociative;
00775 break;
00776 };
00777
00778 int slong = sizeof(void*);
00779 switch ( fSTL_type ) {
00780 case TClassEdit::kMap:
00781 case TClassEdit::kMultiMap:
00782 nam = "pair<"+inside[1]+","+inside[2];
00783 nam += (nam[nam.length()-1]=='>') ? " >" : ">";
00784 fValue = R__CreateValue(nam);
00785
00786 fVal = R__CreateValue(inside[2]);
00787 fKey = R__CreateValue(inside[1]);
00788 fPointers = fPointers || (0 != (fKey->fCase&G__BIT_ISPOINTER));
00789 if ( 0 == fValDiff ) {
00790 fValDiff = fKey->fSize + fVal->fSize;
00791 fValDiff += (slong - fKey->fSize%slong)%slong;
00792 fValDiff += (slong - fValDiff%slong)%slong;
00793 }
00794 if ( 0 == fValOffset ) {
00795 fValOffset = fKey->fSize;
00796 fValOffset += (slong - fKey->fSize%slong)%slong;
00797 }
00798 break;
00799 case TClassEdit::kBitSet:
00800 inside[1] = "bool";
00801
00802 default:
00803 fValue = R__CreateValue(inside[1]);
00804
00805 fVal = new Value(*fValue);
00806 if ( 0 == fValDiff ) {
00807 fValDiff = fVal->fSize;
00808 fValDiff += (slong - fValDiff%slong)%slong;
00809 }
00810 break;
00811 }
00812
00813 fPointers = fPointers || (0 != (fVal->fCase&G__BIT_ISPOINTER));
00814 fClass = cl;
00815 return this;
00816 }
00817 Fatal("TGenCollectionProxy","Components of %s not analysed!",cl->GetName());
00818 }
00819 Fatal("TGenCollectionProxy","Collection class %s not found!",fTypeinfo.name());
00820 return 0;
00821 }
00822
00823
00824 TClass *TGenCollectionProxy::GetCollectionClass()
00825 {
00826
00827 return fClass ? fClass : Initialize()->fClass;
00828 }
00829
00830
00831 Int_t TGenCollectionProxy::GetCollectionType()
00832 {
00833
00834
00835 if (!fClass) {
00836 Initialize();
00837 }
00838 return fSTL_type;
00839 }
00840
00841
00842 ULong_t TGenCollectionProxy::GetIncrement() {
00843
00844
00845 if (!fValue) {
00846 Initialize();
00847 }
00848 return fValDiff;
00849 }
00850
00851
00852 UInt_t TGenCollectionProxy::Sizeof() const
00853 {
00854
00855 return fClass->Size();
00856 }
00857
00858
00859 Bool_t TGenCollectionProxy::HasPointers() const
00860 {
00861
00862
00863
00864 if( !fValue )
00865 Initialize();
00866
00867
00868
00869
00870 return fPointers && !(fSTL_type == TClassEdit::kMap || fSTL_type == TClassEdit::kMultiMap);
00871 }
00872
00873
00874 TClass *TGenCollectionProxy::GetValueClass()
00875 {
00876
00877
00878 if (!fValue) Initialize();
00879 return fValue ? fValue->fType.GetClass() : 0;
00880 }
00881
00882
00883 void TGenCollectionProxy::SetValueClass(TClass *new_Value_type)
00884 {
00885
00886
00887 if (!fValue) Initialize();
00888 fValue->fType = new_Value_type;
00889 }
00890
00891
00892 EDataType TGenCollectionProxy::GetType()
00893 {
00894
00895
00896 if ( !fValue ) Initialize();
00897 return fValue->fKind;
00898 }
00899
00900
00901 void* TGenCollectionProxy::At(UInt_t idx)
00902 {
00903
00904 if ( fEnv && fEnv->fObject ) {
00905 switch (fSTL_type) {
00906 case TClassEdit::kVector:
00907 fEnv->fIdx = idx;
00908 switch( idx ) {
00909 case 0:
00910 return fEnv->fStart = fFirst.invoke(fEnv);
00911 default:
00912 if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00913 return ((char*)fEnv->fStart) + fValDiff*idx;
00914 }
00915 case TClassEdit::kSet:
00916 case TClassEdit::kMultiSet:
00917 case TClassEdit::kMap:
00918 case TClassEdit::kMultiMap:
00919 if ( fEnv->fUseTemp ) {
00920 return (((char*)fEnv->fTemp)+idx*fValDiff);
00921 }
00922
00923 default:
00924 switch( idx ) {
00925 case 0:
00926 fEnv->fIdx = idx;
00927 return fEnv->fStart = fFirst.invoke(fEnv);
00928 default: {
00929 fEnv->fIdx = idx - fEnv->fIdx;
00930 if (! fEnv->fStart ) fEnv->fStart = fFirst.invoke(fEnv);
00931 void* result = fNext.invoke(fEnv);
00932 fEnv->fIdx = idx;
00933 return result;
00934 }
00935 }
00936 }
00937 }
00938 Fatal("TGenCollectionProxy","At> Logic error - no proxy object set.");
00939 return 0;
00940 }
00941
00942
00943 void TGenCollectionProxy::Clear(const char* opt)
00944 {
00945
00946 if ( fEnv && fEnv->fObject ) {
00947 if ( fPointers && opt && *opt=='f' ) {
00948 size_t i, n = *(size_t*)fSize.invoke(fEnv);
00949 if ( n > 0 ) {
00950 for (i=0; i<n; ++i)
00951 DeleteItem(true, TGenCollectionProxy::At(i));
00952 }
00953 }
00954 fClear.invoke(fEnv);
00955 }
00956 }
00957
00958
00959 UInt_t TGenCollectionProxy::Size() const
00960 {
00961
00962 if ( fEnv && fEnv->fObject ) {
00963 if (fEnv->fUseTemp) {
00964 return fEnv->fSize;
00965 } else {
00966 return *(size_t*)fSize.invoke(fEnv);
00967 }
00968 }
00969 Fatal("TGenCollectionProxy","Size> Logic error - no proxy object set.");
00970 return 0;
00971 }
00972
00973
00974 void TGenCollectionProxy::Resize(UInt_t n, Bool_t force)
00975 {
00976
00977 if ( fEnv && fEnv->fObject ) {
00978 if ( force && fPointers ) {
00979 size_t i, nold = *(size_t*)fSize.invoke(fEnv);
00980 if ( n != nold ) {
00981 for (i=n; i<nold; ++i)
00982 DeleteItem(true, *(void**)TGenCollectionProxy::At(i));
00983 }
00984 }
00985 MESSAGE(3, "Resize(n)" );
00986 fEnv->fSize = n;
00987 fResize(fEnv->fObject,fEnv->fSize);
00988 return;
00989 }
00990 Fatal("TGenCollectionProxy","Resize> Logic error - no proxy object set.");
00991 }
00992
00993
00994 void* TGenCollectionProxy::Allocate(UInt_t n, Bool_t )
00995 {
00996
00997
00998
00999
01000 if ( fEnv && fEnv->fObject ) {
01001 switch ( fSTL_type ) {
01002 case TClassEdit::kSet:
01003 case TClassEdit::kMultiSet:
01004 case TClassEdit::kMap:
01005 case TClassEdit::kMultiMap:
01006 if ( fPointers )
01007 Clear("force");
01008 else
01009 fClear.invoke(fEnv);
01010 ++fEnv->fRefCount;
01011 fEnv->fSize = n;
01012
01013 TStaging *s;
01014 if (fStaged.empty()) {
01015 s = new TStaging(n,fValDiff);
01016 } else {
01017 s = fStaged.back();
01018 fStaged.pop_back();
01019 s->Resize(n);
01020 }
01021 fConstruct(s->GetContent(),s->GetSize());
01022
01023 s->SetTarget(fEnv->fObject);
01024
01025 fEnv->fTemp = s->GetContent();
01026 fEnv->fUseTemp = kTRUE;
01027 fEnv->fStart = fEnv->fTemp;
01028
01029 return s;
01030 case TClassEdit::kVector:
01031 case TClassEdit::kList:
01032 case TClassEdit::kDeque:
01033 if( fPointers ) {
01034 Clear("force");
01035 }
01036 fEnv->fSize = n;
01037 fResize(fEnv->fObject,n);
01038 return fEnv->fObject;
01039
01040 case TClassEdit::kBitSet:
01041
01042 return fEnv->fObject;
01043 }
01044 }
01045 return 0;
01046 }
01047
01048
01049 void TGenCollectionProxy::Commit(void* from)
01050 {
01051
01052
01053 if (fProperties & kIsAssociative) {
01054
01055
01056
01057
01058 if ( from ) {
01059 TStaging *s = (TStaging*) from;
01060 if ( s->GetTarget() ) {
01061 fFeed(s->GetContent(),s->GetTarget(),s->GetSize());
01062 }
01063 fDestruct(s->GetContent(),s->GetSize());
01064 s->SetTarget(0);
01065 fStaged.push_back(s);
01066 }
01067 }
01068 }
01069
01070
01071 void TGenCollectionProxy::PushProxy(void *objstart)
01072 {
01073
01074
01075 gSlowIterator__Proxy.push_back(this);
01076
01077 if ( !fValue ) Initialize();
01078 if ( !fProxyList.empty() ) {
01079 EnvironBase_t* back = fProxyList.back();
01080 if ( back->fObject == objstart ) {
01081 ++back->fRefCount;
01082 fProxyList.push_back(back);
01083 fEnv = back;
01084 return;
01085 }
01086 }
01087 EnvironBase_t* e = 0;
01088 if ( fProxyKept.empty() ) {
01089 e = (EnvironBase_t*)fCreateEnv.invoke();
01090 e->fTemp = 0;
01091 e->fUseTemp = kFALSE;
01092 }
01093 else {
01094 e = fProxyKept.back();
01095 fProxyKept.pop_back();
01096 }
01097 e->fSize = 0;
01098 e->fRefCount = 1;
01099 e->fObject = objstart;
01100 e->fStart = 0;
01101 e->fIdx = 0;
01102
01103 fProxyList.push_back(e);
01104 fEnv = e;
01105 }
01106
01107
01108 void TGenCollectionProxy::PopProxy()
01109 {
01110
01111
01112 gSlowIterator__Proxy.pop_back();
01113
01114 if ( !fProxyList.empty() ) {
01115 EnvironBase_t* e = fProxyList.back();
01116 if ( --e->fRefCount <= 0 ) {
01117 fProxyKept.push_back(e);
01118 e->fUseTemp = kFALSE;
01119 }
01120 fProxyList.pop_back();
01121 }
01122 fEnv = fProxyList.empty() ? 0 : fProxyList.back();
01123 }
01124
01125
01126 void TGenCollectionProxy::DeleteItem(Bool_t force, void* ptr) const
01127 {
01128
01129 if ( force && ptr ) {
01130 switch (fSTL_type) {
01131 case TClassEdit::kMap:
01132 case TClassEdit::kMultiMap:
01133 if ( fKey->fCase&G__BIT_ISPOINTER ) {
01134 fKey->DeleteItem(*(void**)ptr);
01135 }
01136 if ( fVal->fCase&G__BIT_ISPOINTER ) {
01137 char *addr = ((char*)ptr)+fValOffset;
01138 fVal->DeleteItem(*(void**)addr);
01139 }
01140 break;
01141 default:
01142 if ( fVal->fCase&G__BIT_ISPOINTER ) {
01143 fVal->DeleteItem(*(void**)ptr);
01144 }
01145 break;
01146 }
01147 }
01148 }
01149
01150
01151 void TGenCollectionProxy::ReadBuffer(TBuffer & , void * , const TClass * )
01152 {
01153 MayNotUse("TGenCollectionProxy::ReadBuffer(TBuffer &, void *, const TClass *)");
01154 }
01155
01156
01157 void TGenCollectionProxy::ReadBuffer(TBuffer & , void * )
01158 {
01159 MayNotUse("TGenCollectionProxy::ReadBuffer(TBuffer &, void *)");
01160 }
01161
01162
01163 void TGenCollectionProxy::Streamer(TBuffer &buff)
01164 {
01165
01166 if ( fEnv ) {
01167 GetCollectionClass()->Streamer( fEnv->fObject, buff );
01168 return;
01169 }
01170 Fatal("TGenCollectionProxy","Streamer> Logic error - no proxy object set.");
01171 }
01172
01173
01174 void TGenCollectionProxy::Streamer(TBuffer &buff, void *objp, int )
01175 {
01176
01177 TPushPop env(this, objp);
01178 Streamer(buff);
01179 }
01180
01181
01182 void TGenCollectionProxy::operator()(TBuffer &b, void *objp)
01183 {
01184
01185 Streamer(b, objp, 0);
01186 }
01187
01188
01189 struct TGenCollectionProxy__SlowIterator {
01190 TVirtualCollectionProxy *fProxy;
01191 UInt_t fIndex;
01192 TGenCollectionProxy__SlowIterator(TVirtualCollectionProxy *proxy) : fProxy(proxy), fIndex(0) {}
01193 };
01194
01195
01196 void TGenCollectionProxy__SlowCreateIterators(void * , void **begin_arena, void **end_arena)
01197 {
01198 new (*begin_arena) TGenCollectionProxy__SlowIterator(gSlowIterator__Proxy.back());
01199 *(UInt_t*)*end_arena = gSlowIterator__Proxy.back()->Size();
01200 }
01201
01202
01203 void *TGenCollectionProxy__SlowNext(void *iter, const void *end)
01204 {
01205 TGenCollectionProxy__SlowIterator *iterator = (TGenCollectionProxy__SlowIterator*)iter;
01206 if (iterator->fIndex != *(UInt_t*)end) {
01207 void *result = iterator->fProxy->At(iterator->fIndex);
01208 ++(iterator->fIndex);
01209 return result;
01210 } else {
01211 return 0;
01212 }
01213 }
01214
01215
01216 void * TGenCollectionProxy__SlowCopyIterator(void *dest, const void *source)
01217 {
01218 *(TGenCollectionProxy__SlowIterator*)dest = *(TGenCollectionProxy__SlowIterator*)source;
01219 return dest;
01220 }
01221
01222
01223 void TGenCollectionProxy__SlowDeleteSingleIterators(void *)
01224 {
01225
01226 }
01227
01228
01229 void TGenCollectionProxy__SlowDeleteTwoIterators(void *, void *)
01230 {
01231
01232 }
01233
01234
01235
01236 void TGenCollectionProxy__VectorCreateIterators(void *obj, void **begin_arena, void **end_arena)
01237 {
01238
01239
01240 std::vector<char> *vec = (std::vector<char>*)obj;
01241 if (vec->empty()) {
01242 *begin_arena = 0;
01243 *end_arena = 0;
01244 return;
01245 }
01246 *begin_arena = &(*vec->begin());
01247 #ifdef R__VISUAL_CPLUSPLUS
01248 *end_arena = &(*(vec->end()-1)) + 1;
01249 #else
01250
01251 *end_arena = &(*vec->end());
01252 #endif
01253
01254
01255
01256
01257
01258 }
01259
01260
01261 void *TGenCollectionProxy__VectorNext(void *, const void *)
01262 {
01263
01264 R__ASSERT(0);
01265 return 0;
01266 }
01267
01268
01269 void *TGenCollectionProxy__VectorCopyIterator(void *dest, const void *source)
01270 {
01271 *(void**)dest = *(void**)source;
01272 return dest;
01273 }
01274
01275
01276 void TGenCollectionProxy__VectorDeleteSingleIterators(void *)
01277 {
01278
01279 }
01280
01281
01282 void TGenCollectionProxy__VectorDeleteTwoIterators(void *, void *)
01283 {
01284
01285 }
01286
01287
01288
01289
01290 void TGenCollectionProxy__StagingCreateIterators(void *obj, void **begin_arena, void **end_arena)
01291 {
01292 TGenCollectionProxy::TStaging * s = (TGenCollectionProxy::TStaging*)obj;
01293 *begin_arena = s->GetContent();
01294 *end_arena = s->GetEnd();
01295 }
01296
01297
01298 void *TGenCollectionProxy__StagingNext(void *, const void *)
01299 {
01300
01301 R__ASSERT(0);
01302 return 0;
01303 }
01304
01305
01306 void *TGenCollectionProxy__StagingCopyIterator(void *dest, const void *source)
01307 {
01308 *(void**)dest = *(void**)source;
01309 return dest;
01310 }
01311
01312
01313 void TGenCollectionProxy__StagingDeleteSingleIterators(void *)
01314 {
01315
01316 }
01317
01318
01319 void TGenCollectionProxy__StagingDeleteTwoIterators(void *, void *)
01320 {
01321
01322 }
01323
01324
01325
01326 TVirtualCollectionProxy::CreateIterators_t TGenCollectionProxy::GetFunctionCreateIterators(Bool_t read)
01327 {
01328
01329
01330
01331
01332
01333 if ( fFunctionCreateIterators ) return fFunctionCreateIterators;
01334
01335 if ( !fValue ) InitializeEx();
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345 if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated))
01346 fFunctionCreateIterators = TGenCollectionProxy__VectorCreateIterators;
01347 else if ( (fProperties & kIsAssociative) && read)
01348 fFunctionCreateIterators = TGenCollectionProxy__StagingCreateIterators;
01349 else
01350 fFunctionCreateIterators = TGenCollectionProxy__SlowCreateIterators;
01351 return fFunctionCreateIterators;
01352 }
01353
01354
01355 TVirtualCollectionProxy::CopyIterator_t TGenCollectionProxy::GetFunctionCopyIterator(Bool_t read)
01356 {
01357
01358
01359
01360
01361
01362 if ( !fValue ) InitializeEx();
01363
01364 if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated))
01365 return TGenCollectionProxy__VectorCopyIterator;
01366 else if ( (fProperties & kIsAssociative) && read)
01367 return TGenCollectionProxy__StagingCopyIterator;
01368 else
01369 return TGenCollectionProxy__SlowCopyIterator;
01370 }
01371
01372
01373 TVirtualCollectionProxy::Next_t TGenCollectionProxy::GetFunctionNext(Bool_t read)
01374 {
01375
01376
01377
01378
01379
01380
01381 if ( !fValue ) InitializeEx();
01382
01383 if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated))
01384 return TGenCollectionProxy__VectorNext;
01385 else if ( (fProperties & kIsAssociative) && read)
01386 return TGenCollectionProxy__StagingNext;
01387 else
01388 return TGenCollectionProxy__SlowNext;
01389 }
01390
01391
01392 TVirtualCollectionProxy::DeleteIterator_t TGenCollectionProxy::GetFunctionDeleteIterator(Bool_t read)
01393 {
01394
01395
01396
01397
01398 if ( !fValue ) InitializeEx();
01399
01400 if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated))
01401 return TGenCollectionProxy__VectorDeleteSingleIterators;
01402 else if ( (fProperties & kIsAssociative) && read)
01403 return TGenCollectionProxy__StagingDeleteSingleIterators;
01404 else
01405 return TGenCollectionProxy__SlowDeleteSingleIterators;
01406 }
01407
01408
01409 TVirtualCollectionProxy::DeleteTwoIterators_t TGenCollectionProxy::GetFunctionDeleteTwoIterators(Bool_t read)
01410 {
01411
01412
01413
01414
01415 if ( fFunctionDeleteTwoIterators ) return fFunctionDeleteTwoIterators;
01416
01417 if ( !fValue ) InitializeEx();
01418
01419 if (fSTL_type==TClassEdit::kVector || (fProperties & kIsEmulated))
01420 fFunctionDeleteTwoIterators = TGenCollectionProxy__VectorDeleteTwoIterators;
01421 else if ( (fProperties & kIsAssociative) && read)
01422 fFunctionDeleteTwoIterators = TGenCollectionProxy__StagingDeleteTwoIterators;
01423 else
01424 fFunctionDeleteTwoIterators = TGenCollectionProxy__SlowDeleteTwoIterators;
01425 return fFunctionDeleteTwoIterators;
01426 }
01427
01428
01429 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version)
01430 {
01431
01432
01433
01434 TObjArray* arr = 0;
01435 TStreamerInfoActions::TActionSequence *result = 0;
01436 if (fConversionReadMemberWise) {
01437 std::map<std::string, TObjArray*>::iterator it;
01438
01439 it = fConversionReadMemberWise->find( oldClass->GetName() );
01440
01441 if( it != fConversionReadMemberWise->end() ) {
01442 arr = it->second;
01443 }
01444
01445 if (arr) {
01446 result = (TStreamerInfoActions::TActionSequence *)arr->At(version);
01447 if (result) {
01448 return result;
01449 }
01450 }
01451 }
01452
01453
01454 TClass *valueClass = GetValueClass();
01455 if (valueClass == 0) {
01456 return 0;
01457 }
01458 TVirtualStreamerInfo *info = valueClass->GetConversionStreamerInfo(oldClass,version);
01459 if (info == 0) {
01460 return 0;
01461 }
01462 result = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*this);
01463
01464 if (!arr) {
01465 arr = new TObjArray(version+10, -1);
01466 if (!fConversionReadMemberWise) {
01467 fConversionReadMemberWise = new std::map<std::string, TObjArray*>();
01468 }
01469 (*fConversionReadMemberWise)[oldClass->GetName()] = arr;
01470 }
01471 arr->AddAtAndExpand( result, version );
01472
01473 return result;
01474 }
01475
01476
01477 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetReadMemberWiseActions(Int_t version)
01478 {
01479
01480
01481
01482 TStreamerInfoActions::TActionSequence *result = 0;
01483 if (version < (fReadMemberWise->GetSize()-1)) {
01484 result = (TStreamerInfoActions::TActionSequence *)fReadMemberWise->At(version);
01485 }
01486 if (result == 0) {
01487
01488 TClass *valueClass = GetValueClass();
01489 TVirtualStreamerInfo *info = 0;
01490 if (valueClass) {
01491 info = valueClass->GetStreamerInfo(version);
01492 }
01493 result = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*this);
01494 fReadMemberWise->AddAtAndExpand(result,version);
01495 }
01496 return result;
01497 }
01498
01499
01500 TStreamerInfoActions::TActionSequence *TGenCollectionProxy::GetWriteMemberWiseActions()
01501 {
01502
01503
01504 R__ASSERT(0 );
01505 return 0;
01506 }
01507