1 #include <assert.h> 2 #include <stdlib.h> 3 #include "StArray.h" 4 #include "TDatime.h" 5 #include "TBrowser.h" 6 #include "StMkDeb.h" 7 8 enum {kBelongs = BIT(22)}; 9 //______________________________________________________________________________ 10 ClassImp(StObjLink) 11 //______________________________________________________________________________ 12 void StObjLink::Browse(TBrowser* b) {b->Add(fLink);} 13 //______________________________________________________________________________ 14 void StObjLink::Streamer(TBuffer &R__b) 15 { 16 17 if (R__b.IsReading()) { 18 fLink = 0; 19 UInt_t ubj; 20 R__b >> ubj ; 21 if (!ubj) return; 22 StProxyUrr *urr = new StProxyUrr(&fLink); 23 urr->push_back(ubj); 24 StXRefManager::fgManager->AddColl(urr); 25 26 } else { 27 const static UInt_t kMustBeOne = kIsOnHeap | kNotDeleted; 28 const static UInt_t kMustBeZero = kCanDelete | kObjInCanvas | kHasUUID 29 | kCannotPick| kNoContextMenu| kZombie; 30 if (!fLink || fLink->TestBits(kMustBeZero|kMustBeOne) !=(int)kMustBeOne) 31 fLink = 0; 32 if (!fLink) R__b << UInt_t(0); 33 else fLink->Ztreamer(R__b); 34 } 35 } 36 37 //______________________________________________________________________________ 38 39 ClassImp(StObjArray) 40 //______________________________________________________________________________ 41 Int_t StObjArray::getEntries() const 42 { 43 int sz = size(); 44 int en = 0; 45 for (int i=0;i<sz;i++) 46 { 47 TObject *to = fV[i]; 48 if (!to) continue; 49 if (to->IsZombie()) continue; 50 en++; 51 } 52 return en; 53 } 54 //______________________________________________________________________________ 55 TObject** StObjArray::Erase(TObject** it,int del) 56 { 57 int i = it-&fV[0]; 58 if (del) {delete fV[i]; fV[i]=0;} 59 return &(*(fV.erase(fV.begin()+i))); 60 } 61 //______________________________________________________________________________ 62 TObject** StObjArray::Erase(TObject** fst,TObject** lst,int del) 63 { 64 int ifst = fst-&fV[0]; 65 int ilst = lst-&fV[0]; 66 if (del) {for (int i=ifst;i<ilst;i++) {delete fV[i];fV[i]=0;}} 67 return &(*(fV.erase(fV.begin()+ifst,fV.begin()+ilst))); 68 } 69 //______________________________________________________________________________ 70 TObject* StObjArray::find(const char *name) const 71 { 72 int n = fV.size(); 73 for (int i=0;i<n;i++) { 74 if (!fV[i]) continue; 75 if (!strcmp(name,fV[i]->GetName())) return (TObject*)fV[i]; 76 } 77 return 0; 78 } 79 //______________________________________________________________________________ 80 void StObjArray::Streamer(TBuffer &b) 81 { 82 83 // Stream all objects in the array to or from the I/O buffer. 84 85 Int_t nobjects; 86 if (b.IsReading()) { 87 Version_t v = b.ReadVersion(); if (v){/*touch*/} 88 clear(); 89 b >> nobjects; 90 if (!nobjects) return; 91 resize(nobjects); 92 TObject *obj; 93 for (Int_t i = 0; i < nobjects; i++) { 94 b >> obj; fV[i] =(obj);} 95 } else { 96 b.WriteVersion(Class()); 97 nobjects = getEntries(); 98 b << nobjects; 99 100 for (Int_t i = 0; nobjects; i++) { 101 TObject *to = at(i); 102 if (to && !to->IsZombie()) {b << to; nobjects--;} 103 } 104 } 105 } 106 107 108 109 //______________________________________________________________________________ 110 void StObjArray::Browse(TBrowser *b) 111 { 112 enum { maxBrowsable = 5000}; 113 114 // Browse this collection (called by TBrowser). 115 // If b=0, there is no Browse call TObject::Browse(0) instead. 116 // This means TObject::Inspect() will be invoked indirectly 117 118 if (!b) return; 119 TObject *obj=0; 120 121 Int_t counter = 0; 122 Int_t totalSize = size(); 123 for (int i=0; i<totalSize && ++counter < maxBrowsable ; i++) { 124 obj = at(i); if (!obj || ((ULong_t)obj)&1) continue; 125 TString browseName(obj->GetName()); 126 if (browseName.IsNull()) browseName = obj->ClassName(); 127 char buffer[100]; 128 sprintf(buffer,"_%d(%d)",counter,totalSize); 129 browseName += buffer; 130 b->Add(obj,browseName.Data()); 131 } 132 } 133 //______________________________________________________________________________ 134 Bool_t StObjArray::IsFolder() const 135 { return size();} 136 137 //______________________________________________________________________________ 138 void StObjArray::random_shuffle(int start,int end) 139 { 140 141 int lst = size(); 142 if (start >= lst) return; 143 if (end > lst) end = lst; 144 ::random_shuffle(begin()+start,begin()+end); 145 146 } 147 //______________________________________________________________________________ 148 void StObjArray::ls(const char *tit) const 149 { 150 if (!tit) tit =""; 151 int n = fV.size(); 152 Info("ls","%s(%s)[%d]",ClassName(),tit,n); 153 for (int i=0;i<n;i++) { 154 TObject *to = fV[i]; if (!to) continue; 155 printf("%4d - %p %s(%s)\n",i, (void*)to,to->ClassName(),to->GetName()); 156 } 157 } 158 159 //______________________________________________________________________________ 160 ClassImp(StRefArray) 161 StRefArray::StRefArray(Int_t sz):StObjArray(sz){}; 162 StRefArray::StRefArray(const StRefArray &from):StObjArray(from){}; 163 164 //______________________________________________________________________________ 165 void StRefArray::Streamer(TBuffer &R__b) 166 { 167 168 // Stream all objects in the array to or from the I/O buffer. 169 170 Int_t nobjects; 171 if (R__b.IsReading()) { 172 Version_t v = R__b.ReadVersion(); if (v){/*touch*/} 173 clear(); 174 R__b >> nobjects; 175 if (!nobjects) return; 176 if (v <=2 || nobjects>0) { //OLD non split format 177 TObject *obj; 178 for (Int_t i = 0; i < nobjects; i++) { 179 R__b >> obj; push_back(obj);} 180 } else { //SPLIT format 181 UInt_t ubj; 182 nobjects = -nobjects; 183 StProxyUrr *urr = new StProxyUrr(this); 184 for (Int_t i = 0; i < nobjects; i++) { 185 R__b >> ubj ; urr->push_back(ubj); 186 } 187 StXRefManager::fgManager->AddColl(urr); 188 } 189 190 } else { 191 R__b.WriteVersion(Class()); 192 int nobjs = nobjects = getEntries(); 193 if (StObject::fgTally) nobjs=-nobjs; 194 R__b << nobjs; 195 if (!nobjects) return; 196 TObject *to; 197 for (Int_t i = 0; nobjects; i++) { 198 to = at(i); 199 if (!to) continue; 200 if (to->IsZombie()) continue; 201 nobjects--; 202 if (nobjs<0) {((StObject*)to)->Ztreamer(R__b);} 203 else { R__b << to; } 204 } 205 } 206 } 207 208 //______________________________________________________________________________ 209 ClassImp(StStrArray) 210 //______________________________________________________________________________ 211 StStrArray::StStrArray(Int_t sz):StObjArray(sz){} 212 //______________________________________________________________________________ 213 void StStrArray::operator=(const StStrArray &a) 214 { 215 int n,i; TObject *sto; 216 217 clear(); 218 n = a.size(); 219 resize(n); 220 for (i=0; i<n; i++) 221 { 222 sto = a[i]; 223 if (sto) sto = ((StObject*)sto)->clone(); 224 sto->ResetBit(kBelongs); 225 put_at(sto,i); 226 } 227 } 228 //______________________________________________________________________________ 229 StStrArray::StStrArray(const StStrArray &from){ *this = from;} 230 //______________________________________________________________________________ 231 void StStrArray::clear() 232 { 233 assert(!fV.size() || !fV[0] || ((TObject*)fV[0])->TestBit(TObject::kNotDeleted)); 234 int n,i; 235 236 n = fV.size(); 237 for (i=0; i<n; i++){ 238 TObject *to = fV[i]; 239 if (!to) continue; 240 if (to->TObject::TestBit(TObject::kNotDeleted)) { 241 delete fV[i]; 242 } else { 243 Warning("clear","Object[%d]=%p is already deleted",i,to); 244 #if 0 245 const char *mk=0; 246 mk = StMkDeb::GetName(StMkDeb::GetCurrent()); 247 if (mk && *mk) printf("*** Now we are in %s ***\n",mk); 248 mk = StMkDeb::GetUser(to); 249 if (mk && *mk) printf("*** It was deleted in maker %s ***\n",mk); 250 #endif 251 // assert(0); 252 } 253 fV[i]=0; 254 } 255 fV.clear(); 256 } 257 StStrArray::~StStrArray() 258 { 259 clear(); 260 } 261 //______________________________________________________________________________ 262 void StStrArray::put_at(TObject *obj,int i) 263 { 264 assert(i>=0 && i<int(size())); 265 if (obj) { 266 if (fV[i]==obj) return; 267 assert(!obj->TestBit(kBelongs) && obj->TestBit(TObject::kNotDeleted)); 268 obj->SetBit(kBelongs); 269 } 270 fV[i]=obj;} 271 //______________________________________________________________________________ 272 void StStrArray::push_back(const TObject * const to) 273 { 274 TObject* obj = (TObject*)to; 275 if (obj) { 276 assert(!obj->TestBit(kBelongs) && obj->TestBit(TObject::kNotDeleted)); 277 obj->SetBit(kBelongs); 278 } 279 280 fV.push_back(obj); 281 } 282 283 //______________________________________________________________________________ 284 void StStrArray::Streamer(TBuffer &R__b) 285 { 286 // Stream an object of class StStrArray. 287 if (R__b.IsReading()) { 288 Version_t R__v = R__b.ReadVersion(); if (R__v) { } 289 StObjArray::Streamer(R__b); 290 if (R__v >=3) 291 StXRefManager::fgManager->AddColl(this); 292 } else { 293 R__b.WriteVersion(Class()); 294 StObjArray::Streamer(R__b); 295 } 296 297 } 298 //______________________________________________________________________________ 299 void StStrArray::makeZombie(int flg) 300 { 301 StObject::makeZombie(flg); 302 int n = size(); 303 for (int i=0;i<n;i++) 304 { StObject *o = (StObject*)at(i); if (o) o->makeZombie(flg);} 305 } 306 //______________________________________________________________________________ 307 308 309 310 311