ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/UserCode/MitAna/DataCont/interface/RefArray.h
Revision: 1.23
Committed: Sun Sep 19 23:46:08 2010 UTC (14 years, 7 months ago) by bendavid
Content type: text/plain
Branch: MAIN
CVS Tags: Mit_025c_branch2, Mit_025c_branch1, Mit_025c_branch0, Mit_025d, Mit_025c, Mit_025b, Mit_025a, Mit_025, Mit_025pre2, Mit_024b, Mit_025pre1, Mit_024a, Mit_024, Mit_023, Mit_022a, Mit_022, Mit_020d, TMit_020d, Mit_020c, Mit_021, Mit_021pre2, Mit_021pre1, Mit_020b, Mit_020a, Mit_020, Mit_020pre1, Mit_018, Mit_017, Mit_017pre3, Mit_017pre2, Mit_017pre1, Mit_016, Mit_015b, Mit_015a, Mit_015, Mit_014e
Branch point for: Mit_025c_branch
Changes since 1.22: +6 -2 lines
Log Message:
add hard protections for null pointers from refs

File Contents

# User Rev Content
1 loizides 1.1 //--------------------------------------------------------------------------------------------------
2 bendavid 1.23 // $Id: RefArray.h,v 1.22 2009/03/23 22:15:10 loizides Exp $
3 loizides 1.1 //
4     // RefArray
5     //
6 loizides 1.16 // Implementation of an efficient TRefArray using the FastArray.
7 bendavid 1.7 //
8 loizides 1.16 // RefArray now supports objects from multiple PIDs, but only a single
9     // PID will be stored as long as only objects from a single PID are added.
10 loizides 1.1 //
11     // Authors: C.Loizides, J.Bendavid
12     //--------------------------------------------------------------------------------------------------
13    
14 loizides 1.17 #ifndef MITANA_DATACONT_REFARRAY_H
15     #define MITANA_DATACONT_REFARRAY_H
16 loizides 1.1
17     #include <TObject.h>
18     #include <TRefArray.h>
19     #include <TRefTable.h>
20     #include <TProcessID.h>
21     #include <TError.h>
22 loizides 1.16 #include "MitAna/DataCont/interface/RefResolver.h"
23 loizides 1.1 #include "MitAna/DataCont/interface/Collection.h"
24 bendavid 1.15 #include "MitAna/DataCont/interface/FastArray.h"
25     #include "MitAna/DataCont/interface/FastArrayBasic.h"
26 bendavid 1.7 #include "MitAna/DataCont/interface/ProcIDRef.h"
27 loizides 1.1
28     namespace mithep
29     {
30 bendavid 1.15 template<class ArrayElement>
31 loizides 1.16 class RefArray : public Collection<ArrayElement>
32 loizides 1.1 {
33     public:
34     RefArray();
35    
36 loizides 1.9 void Add(const ArrayElement *ae);
37 loizides 1.1 ArrayElement *At(UInt_t idx);
38 loizides 1.8 const ArrayElement *At(UInt_t idx) const;
39 bendavid 1.15 void Clear(Option_t */*opt*/="") { fPIDs.Clear(); fUIDs.Clear(); }
40 loizides 1.18 UInt_t Entries() const { return fUIDs.Entries(); }
41 loizides 1.16 UInt_t GetEntries() const { return fUIDs.GetEntries(); }
42     UInt_t GetSize() const { return fUIDs.GetSize(); }
43 bendavid 1.12 Bool_t HasObject(const ArrayElement *obj) const;
44 loizides 1.8 Bool_t IsOwner() const { return kTRUE; }
45 loizides 1.10 TObject *ObjAt(UInt_t idx);
46     const TObject *ObjAt(UInt_t idx) const;
47 bendavid 1.7 void Reset();
48 loizides 1.16 void Trim() { fPIDs.Trim(); fUIDs.Trim(); }
49 loizides 1.1 ArrayElement *UncheckedAt(UInt_t idx);
50 loizides 1.8 const ArrayElement *UncheckedAt(UInt_t idx) const;
51 loizides 1.1 ArrayElement *operator[](UInt_t idx);
52 loizides 1.8 const ArrayElement *operator[](UInt_t idx) const;
53 loizides 1.1
54     protected:
55 loizides 1.8 TObject *GetObject(UInt_t idx) const;
56 bendavid 1.12 TProcessID *GetPID(UInt_t idx) const;
57 loizides 1.8 UInt_t GetUID(UInt_t idx) const;
58 loizides 1.1
59 loizides 1.16 FastArray<ProcIDRef> fPIDs; //||process ids of referenced objects
60     FastArrayBasic<UInt_t> fUIDs; //||unique ids of referenced objects
61 loizides 1.1
62 loizides 1.16 ClassDef(RefArray, 1) // Implementation of our own TRefArray
63 loizides 1.1 };
64     }
65    
66     //--------------------------------------------------------------------------------------------------
67 bendavid 1.15 template<class ArrayElement>
68     inline mithep::RefArray<ArrayElement>::RefArray()
69 loizides 1.1 {
70 loizides 1.8 // Default constructor.
71 loizides 1.1 }
72    
73     //--------------------------------------------------------------------------------------------------
74 bendavid 1.15 template<class ArrayElement>
75     void mithep::RefArray<ArrayElement>::Add(const ArrayElement *ae)
76 loizides 1.1 {
77 loizides 1.20 // Add reference to object.
78    
79     if (!ae)
80     return;
81 loizides 1.1
82     // check if the object can belong here and assign or get its uid
83     if (ae->TestBit(kHasUUID)) {
84 loizides 1.22 Fatal("Add", "Object cannot be added as it has not UUID!");
85 loizides 1.1 return;
86     }
87    
88 bendavid 1.7 UInt_t uid = 0;
89     TProcessID *pid = 0;
90 loizides 1.1 if (ae->TestBit(kIsReferenced)) {
91     uid = ae->GetUniqueID();
92 loizides 1.9 pid = TProcessID::GetProcessWithUID(uid, const_cast<ArrayElement*>(ae));
93 loizides 1.1 } else {
94 bendavid 1.7 pid = TProcessID::GetSessionProcessID();
95 loizides 1.9 uid = TProcessID::AssignID(const_cast<ArrayElement*>(ae));
96 loizides 1.1 }
97    
98 loizides 1.8 // If RefArray contains one and only one PID reference, then only add another if the added object
99     // has a different PID. When this occurs all of the extra spaces which had been left empty get
100     // filled in with the original PID
101 loizides 1.18 if (fPIDs.Entries()==1) {
102 bendavid 1.7 if (pid != fPIDs.At(0)->Pid() ) {
103 loizides 1.18 while (fPIDs.Entries()<Entries())
104 bendavid 1.15 fPIDs.GetNew()->SetPid(fPIDs.At(0)->Pid());
105 bendavid 1.7
106 bendavid 1.15 fPIDs.GetNew()->SetPid(pid);
107 bendavid 1.7 }
108     }
109     else
110 bendavid 1.15 fPIDs.GetNew()->SetPid(pid);
111 bendavid 1.7
112     fUIDs.Add(uid);
113 loizides 1.21 BaseCollection::Clear();
114 loizides 1.1 }
115    
116     //--------------------------------------------------------------------------------------------------
117 bendavid 1.15 template<class ArrayElement>
118     inline ArrayElement *mithep::RefArray<ArrayElement>::At(UInt_t idx)
119 loizides 1.1 {
120     // Return entry at given index.
121    
122 loizides 1.18 if (idx<Entries())
123 loizides 1.1 return static_cast<ArrayElement*>(GetObject(idx));
124    
125 loizides 1.18 Fatal("At", "Given index (%u) is larger than array size (%u)", idx, Entries());
126 loizides 1.1 return 0;
127     }
128    
129     //--------------------------------------------------------------------------------------------------
130 bendavid 1.15 template<class ArrayElement>
131     inline const ArrayElement *mithep::RefArray<ArrayElement>::At(UInt_t idx) const
132 loizides 1.1 {
133     // Return entry at given index.
134    
135 loizides 1.18 if (idx<Entries())
136 loizides 1.1 return static_cast<const ArrayElement*>(GetObject(idx));
137    
138 loizides 1.18 Fatal("At", "Given index (%u) is larger than array size (%u)", idx, Entries());
139 loizides 1.1 return 0;
140     }
141    
142     //--------------------------------------------------------------------------------------------------
143 bendavid 1.15 template<class ArrayElement>
144     TObject *mithep::RefArray<ArrayElement>::GetObject(UInt_t idx) const
145 loizides 1.1 {
146     // Return entry at given index. Code adapted from TRef::GetObject().
147 loizides 1.8
148 bendavid 1.12 TProcessID *pid = GetPID(idx);
149 loizides 1.1
150 bendavid 1.7 if (!pid) {
151 loizides 1.8 Fatal("GetObject","Process id pointer is null!");
152 loizides 1.1 return 0;
153     }
154    
155 bendavid 1.7 if (!TProcessID::IsValid(pid)) {
156 loizides 1.8 Fatal("GetObject","Process id is invalid!");
157 loizides 1.1 return 0;
158     }
159 loizides 1.8
160 loizides 1.1 UInt_t uid = GetUID(idx);
161 bendavid 1.23 TObject *obj = RefResolver::GetObjectWithID(uid,pid);
162     if (!obj) {
163     Fatal("RefArray::GetObject","Null pointer for filled element!");
164     }
165     return obj;
166 loizides 1.1 }
167    
168     //--------------------------------------------------------------------------------------------------
169 bendavid 1.15 template<class ArrayElement>
170     inline TProcessID *mithep::RefArray<ArrayElement>::GetPID(UInt_t idx) const
171 bendavid 1.12 {
172 loizides 1.20 // Return pid corresponding to given idx.
173 bendavid 1.12
174     TProcessID *pid = 0;
175 loizides 1.18 if (fPIDs.Entries()>1)
176 bendavid 1.15 pid = fPIDs.UncheckedAt(idx)->Pid();
177 bendavid 1.12 else
178 bendavid 1.15 pid = fPIDs.UncheckedAt(0)->Pid();
179 bendavid 1.12
180     return pid;
181     }
182    
183     //--------------------------------------------------------------------------------------------------
184 bendavid 1.15 template<class ArrayElement>
185     inline UInt_t mithep::RefArray<ArrayElement>::GetUID(UInt_t idx) const
186 loizides 1.1 {
187 loizides 1.20 // Return uid corresponding to given idx.
188 loizides 1.1
189 bendavid 1.15 return fUIDs.UncheckedAt(idx);
190 loizides 1.1 }
191    
192     //--------------------------------------------------------------------------------------------------
193 bendavid 1.15 template<class ArrayElement>
194     Bool_t mithep::RefArray<ArrayElement>::HasObject(const ArrayElement *obj) const
195 bendavid 1.12 {
196 loizides 1.20 // Check whether array contains a given object.
197 bendavid 1.12
198     if (!obj->TestBit(kIsReferenced))
199     return kFALSE;
200    
201     UInt_t oUid = obj->GetUniqueID();
202     TProcessID *oPid = TProcessID::GetProcessWithUID(oUid, const_cast<ArrayElement*>(obj));
203    
204 loizides 1.18 for (UInt_t i=0; i<Entries(); ++i) {
205 bendavid 1.12 if ( (GetUID(i)&0xffffff)==(oUid&0xffffff) && GetPID(i)->GetUniqueID()==oPid->GetUniqueID())
206     return kTRUE;
207     }
208    
209     return kFALSE;
210     }
211    
212     //--------------------------------------------------------------------------------------------------
213 bendavid 1.15 template<class ArrayElement>
214     TObject *mithep::RefArray<ArrayElement>::ObjAt(UInt_t idx)
215 loizides 1.10 {
216     // Return object at given index.
217    
218 loizides 1.18 if (idx<Entries())
219 loizides 1.10 return GetObject(idx);
220    
221 loizides 1.18 Fatal("ObjAt", "Given index (%u) is larger than array size (%u)", idx, Entries());
222 loizides 1.10 return 0;
223     }
224    
225     //--------------------------------------------------------------------------------------------------
226 bendavid 1.15 template<class ArrayElement>
227     const TObject *mithep::RefArray<ArrayElement>::ObjAt(UInt_t idx) const
228 loizides 1.10 {
229     // Return object at given index.
230    
231 loizides 1.18 if (idx<Entries())
232 loizides 1.10 return static_cast<const TObject*>(GetObject(idx));
233    
234 loizides 1.18 Fatal("ObjAt", "Given index (%u) is larger than array size (%u)", idx, Entries());
235 loizides 1.10 return 0;
236     }
237    
238     //--------------------------------------------------------------------------------------------------
239 bendavid 1.15 template<class ArrayElement>
240     inline void mithep::RefArray<ArrayElement>::Reset()
241 loizides 1.1 {
242 loizides 1.16 // Reset the array.
243    
244 loizides 1.8 fUIDs.Reset();
245     fPIDs.Reset();
246 loizides 1.19 BaseCollection::Clear();
247 loizides 1.1 }
248    
249     //--------------------------------------------------------------------------------------------------
250 bendavid 1.15 template<class ArrayElement>
251     inline ArrayElement *mithep::RefArray<ArrayElement>::UncheckedAt(UInt_t idx)
252 loizides 1.1 {
253     // Return entry at given index.
254    
255 loizides 1.8 return static_cast<ArrayElement*>(GetObject(idx));
256 loizides 1.1 }
257    
258 bendavid 1.7 //--------------------------------------------------------------------------------------------------
259 bendavid 1.15 template<class ArrayElement>
260     inline const ArrayElement *mithep::RefArray<ArrayElement>::UncheckedAt(UInt_t idx) const
261 bendavid 1.7 {
262 loizides 1.8 // Return entry at given index.
263    
264     return static_cast<const ArrayElement*>(GetObject(idx));
265 loizides 1.1 }
266    
267     //--------------------------------------------------------------------------------------------------
268 bendavid 1.15 template<class ArrayElement>
269     inline const ArrayElement *mithep::RefArray<ArrayElement>::operator[](UInt_t idx) const
270 loizides 1.1 {
271     // Return entry at given index.
272    
273 loizides 1.8 return At(idx);
274 loizides 1.1 }
275    
276     //--------------------------------------------------------------------------------------------------
277 bendavid 1.15 template<class ArrayElement>
278     inline ArrayElement *mithep::RefArray<ArrayElement>::operator[](UInt_t idx)
279 loizides 1.1 {
280     // Return entry at given index.
281    
282 loizides 1.8 return At(idx);
283 loizides 1.1 }
284     #endif