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);
(1) Event cond_true: |
Condition "i < n", taking true branch |
(4) Event loop_begin: |
Jumped back to beginning of loop |
(5) Event cond_true: |
Condition "i < n", taking true branch |
(8) Event loop_begin: |
Jumped back to beginning of loop |
(9) Event cond_true: |
Condition "i < n", taking true branch |
220 for (i=0; i<n; i++)
221 {
222 sto = a[i];
(2) Event cond_true: |
Condition "sto", taking true branch |
(6) Event cond_true: |
Condition "sto", taking true branch |
(10) Event cond_false: |
Condition "sto", taking false branch |
(11) Event if_end: |
End of if statement |
(12) Event var_compare_op: |
Comparing "sto" to null implies that "sto" might be null. |
Also see events: |
[var_deref_model] |
223 if (sto) sto = ((StObject*)sto)->clone();
(13) Event var_deref_model: |
Passing null pointer "sto" to "ResetBit", which dereferences it. [details] |
Also see events: |
[var_compare_op] |
224 sto->ResetBit(kBelongs);
225 put_at(sto,i);
(3) Event loop: |
Jumping back to the beginning of the loop |
(7) Event loop: |
Jumping back to the beginning of the loop |
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