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