1 /* |
|
2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implementation of CCMObjectPool. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "cmobjectpool.h" |
|
20 #include "cmmanagerimpl.h" |
|
21 #include <cmpluginbaseeng.h> |
|
22 #include <cmpluginbase.h> |
|
23 #include <cmconnectionmethoddef.h> |
|
24 |
|
25 #include <e32def.h> |
|
26 #include <e32std.h> |
|
27 |
|
28 |
|
29 ////////////////////////////////////////////////////////////////////// |
|
30 // Construction/Destruction |
|
31 ////////////////////////////////////////////////////////////////////// |
|
32 const TInt KDestGranularity = 20; |
|
33 const TInt KCMethodGranularity = 20; |
|
34 CCMObjectPool::CCMObjectPool(CCmManagerImpl& aCmManagerImpl) : |
|
35 iCmManagerImpl(aCmManagerImpl), |
|
36 iDestinationArray(KDestGranularity, |
|
37 _FOFF(TObjectPoolDestinationItem,iDestinationId)), |
|
38 iConnectionMethodArray(KCMethodGranularity, |
|
39 _FOFF(TObjectPoolCMItem,iConnectionMethodId)) |
|
40 { |
|
41 } |
|
42 |
|
43 CCMObjectPool::~CCMObjectPool() |
|
44 { |
|
45 // The get and remove functions must be used in pairs |
|
46 // If the arrays have any element here than the client |
|
47 // of this class made a programming error |
|
48 for (TInt index = 0; index < iDestinationArray.Count(); index++) |
|
49 { |
|
50 delete iDestinationArray[index].iDestinationItem; |
|
51 } |
|
52 for (TInt index = 0; index < iConnectionMethodArray.Count(); index++) |
|
53 { |
|
54 delete iConnectionMethodArray[index].iConnectionMethodItem; |
|
55 } |
|
56 iDestinationArray.Close(); |
|
57 iConnectionMethodArray.Close(); |
|
58 } |
|
59 |
|
60 CCMObjectPool::TObjectPoolDestinationItem::TObjectPoolDestinationItem( |
|
61 CCmDestinationData* aDestinationItem, |
|
62 TUint32 aDestinationId) : |
|
63 iDestinationId(aDestinationId), |
|
64 iDestinationItem(aDestinationItem) |
|
65 { |
|
66 } |
|
67 |
|
68 CCMObjectPool::TObjectPoolCMItem::TObjectPoolCMItem( |
|
69 CCmPluginBaseEng* aConnectionMethodItem, |
|
70 TUint32 aConnectionMethodId) : |
|
71 iConnectionMethodId(aConnectionMethodId), |
|
72 iConnectionMethodItem(aConnectionMethodItem) |
|
73 { |
|
74 } |
|
75 |
|
76 CCmDestinationImpl* CCMObjectPool::GetDestinationL( TUint32 aDestinationId ) |
|
77 { |
|
78 TUint32 destinationId( aDestinationId ); |
|
79 if ( destinationId > 0 && destinationId < 255 ) |
|
80 { |
|
81 destinationId += KCmDefaultDestinationAPTagId; |
|
82 } |
|
83 TObjectPoolDestinationItem findD( NULL, destinationId ); |
|
84 TInt index = iDestinationArray.FindInUnsignedKeyOrder(findD); |
|
85 if (index == KErrNotFound) |
|
86 { |
|
87 // If the destinaton is not in the pool create it than return it. |
|
88 CCmDestinationImpl* dest = CCmDestinationImpl::NewL( iCmManagerImpl, |
|
89 destinationId ); |
|
90 TObjectPoolDestinationItem aDest( |
|
91 dest->GetData(), |
|
92 destinationId ); |
|
93 User::LeaveIfError( |
|
94 iDestinationArray.InsertInUnsignedKeyOrder(aDest)); |
|
95 dest->IncrementRefCounter(); |
|
96 return dest; |
|
97 } |
|
98 else |
|
99 { |
|
100 // If the destination is allready in the pool than return it. |
|
101 CCmDestinationImpl* dest = CCmDestinationImpl::NewL( iCmManagerImpl, |
|
102 iDestinationArray[index].iDestinationItem ); |
|
103 iDestinationArray[index].iDestinationItem->IncrementRefCounter(); |
|
104 return dest; |
|
105 } |
|
106 } |
|
107 |
|
108 CCmPluginBase* CCMObjectPool::GetConnectionMethodL( TUint32 aCmId, |
|
109 CCmDestinationImpl* aParentDest ) |
|
110 { |
|
111 CCmPluginBase* connMethod = NULL; |
|
112 TObjectPoolCMItem findCM( NULL, aCmId ); |
|
113 TInt index = iConnectionMethodArray.FindInUnsignedKeyOrder(findCM); |
|
114 if (index == KErrNotFound) |
|
115 { |
|
116 CCmPluginBaseEng* pluginBaseEng = iCmManagerImpl.DoFindConnMethL( |
|
117 aCmId, aParentDest); |
|
118 if (!pluginBaseEng) User::Leave(KErrNotFound); //There is no such plugin |
|
119 CleanupStack::PushL( pluginBaseEng ); |
|
120 connMethod = new (ELeave) CCmPluginBase(pluginBaseEng); |
|
121 CleanupStack::PushL( connMethod ); |
|
122 TObjectPoolCMItem aCM( pluginBaseEng, aCmId ); |
|
123 User::LeaveIfError( |
|
124 iConnectionMethodArray.InsertInUnsignedKeyOrder(aCM)); |
|
125 pluginBaseEng->IncrementRefCounter(); |
|
126 CleanupStack::Pop( connMethod ); |
|
127 CleanupStack::Pop( pluginBaseEng ); |
|
128 } |
|
129 else |
|
130 { |
|
131 // If the cm is allready in the pool than return it. |
|
132 iConnectionMethodArray[index].iConnectionMethodItem->IncrementRefCounter(); |
|
133 connMethod = new (ELeave) CCmPluginBase( |
|
134 iConnectionMethodArray[index].iConnectionMethodItem); |
|
135 } |
|
136 return connMethod; |
|
137 } |
|
138 |
|
139 CCmPluginBase* CCMObjectPool::CreateConnectionMethodL( CCmPluginBaseEng* pluginBaseEng ) |
|
140 { |
|
141 CCmPluginBase* connMethod = new (ELeave) CCmPluginBase(pluginBaseEng); |
|
142 CleanupStack::PushL( connMethod ); |
|
143 TObjectPoolCMItem aCM( pluginBaseEng, 0 );//The new id is zero till update |
|
144 User::LeaveIfError( |
|
145 iConnectionMethodArray.InsertInUnsignedKeyOrderAllowRepeats(aCM)); |
|
146 pluginBaseEng->IncrementRefCounter(); |
|
147 CleanupStack::Pop( connMethod ); |
|
148 return connMethod; |
|
149 } |
|
150 |
|
151 void CCMObjectPool::InsertConnectionMethodL( CCmPluginBaseEng* pluginBaseEng ) |
|
152 { |
|
153 TObjectPoolCMItem aCM( pluginBaseEng, 0 );//The new id is zero till update |
|
154 User::LeaveIfError( |
|
155 iConnectionMethodArray.InsertInUnsignedKeyOrderAllowRepeats(aCM)); |
|
156 pluginBaseEng->IncrementRefCounter(); |
|
157 } |
|
158 |
|
159 CCmPluginBase* CCMObjectPool::CreateConnectionMethodL( TUint32 aImplementationUid, |
|
160 TCmPluginInitParam& aParams ) |
|
161 { |
|
162 CCmPluginBaseEng* pluginBaseEng = iCmManagerImpl.DoCreateConnectionMethodL( |
|
163 aImplementationUid, aParams); |
|
164 CleanupStack::PushL( pluginBaseEng ); |
|
165 CCmPluginBase* connMethod = new (ELeave) CCmPluginBase(pluginBaseEng); |
|
166 CleanupStack::PushL( connMethod ); |
|
167 TObjectPoolCMItem aCM( pluginBaseEng, 0 );//The new id is zero till update |
|
168 User::LeaveIfError( |
|
169 iConnectionMethodArray.InsertInUnsignedKeyOrderAllowRepeats(aCM)); |
|
170 pluginBaseEng->IncrementRefCounter(); |
|
171 CleanupStack::Pop( connMethod ); |
|
172 CleanupStack::Pop( pluginBaseEng ); |
|
173 return connMethod; |
|
174 } |
|
175 |
|
176 CCmPluginBase* CCMObjectPool::CreateConnectionMethodL( TUint32 aImplementationUid, |
|
177 TCmPluginInitParam& aParams, |
|
178 TUint32 aConnMethodId ) |
|
179 { |
|
180 CCmPluginBaseEng* pluginBaseEng = iCmManagerImpl.DoCreateConnectionMethodL( |
|
181 aImplementationUid, |
|
182 aParams, |
|
183 aConnMethodId); |
|
184 CleanupStack::PushL( pluginBaseEng ); |
|
185 CCmPluginBase* connMethod = new (ELeave) CCmPluginBase(pluginBaseEng); |
|
186 CleanupStack::PushL( connMethod ); |
|
187 TObjectPoolCMItem aCM( pluginBaseEng, 0 );//The new id is zero till update |
|
188 User::LeaveIfError( |
|
189 iConnectionMethodArray.InsertInUnsignedKeyOrderAllowRepeats(aCM)); |
|
190 pluginBaseEng->IncrementRefCounter(); |
|
191 CleanupStack::Pop( connMethod ); |
|
192 CleanupStack::Pop( pluginBaseEng ); |
|
193 return connMethod; |
|
194 } |
|
195 |
|
196 CCmDestinationImpl* CCMObjectPool::GetDestinationL( const TDesC& aName ) |
|
197 { |
|
198 // CmManagerImpl.GetDestinationL will leave with KErrAlreadyExists |
|
199 // if the destination already exists |
|
200 CCmDestinationImpl* destImpl = CCmDestinationImpl::NewL( iCmManagerImpl, |
|
201 aName ); |
|
202 // Yet destImpl->Id() == 0 |
|
203 TObjectPoolDestinationItem aDest( destImpl->GetData(), destImpl->Id() ); |
|
204 // InsertInUnsignedKeyOrderAllowRepeats is used because all |
|
205 // new destinations' Id is zero |
|
206 User::LeaveIfError( |
|
207 iDestinationArray.InsertInUnsignedKeyOrderAllowRepeats(aDest) ); |
|
208 destImpl->IncrementRefCounter(); |
|
209 return destImpl; |
|
210 } |
|
211 |
|
212 CCmDestinationImpl* CCMObjectPool::CreateDestinationL( const TDesC& aName, |
|
213 TUint32 aDestId ) |
|
214 { |
|
215 // CmManagerImpl.GetDestinationL will leave with KErrAlreadyExists |
|
216 // if the destination already exists |
|
217 CCmDestinationImpl* destImpl = CCmDestinationImpl::NewL( iCmManagerImpl, |
|
218 aName, |
|
219 aDestId); |
|
220 // Yet destImpl->Id() == 0 |
|
221 TObjectPoolDestinationItem aDest( destImpl->GetData(), destImpl->Id() ); |
|
222 // InsertInUnsignedKeyOrderAllowRepeats is used because all |
|
223 // new destinations' Id is zero |
|
224 User::LeaveIfError( |
|
225 iDestinationArray.InsertInUnsignedKeyOrderAllowRepeats(aDest) ); |
|
226 destImpl->IncrementRefCounter(); |
|
227 return destImpl; |
|
228 } |
|
229 |
|
230 |
|
231 void CCMObjectPool::RemoveDestination( CCmDestinationData* aDestination ) |
|
232 { |
|
233 if (aDestination->IdIsValid()) |
|
234 { |
|
235 aDestination->DecrementRefCounter(); |
|
236 if (!aDestination->GetRefCounter()) |
|
237 {// this was the last reference -> must delete |
|
238 TObjectPoolDestinationItem findD( NULL, aDestination->Id() ); |
|
239 TInt index = iDestinationArray.FindInUnsignedKeyOrder(findD); |
|
240 iDestinationArray.Remove(index); |
|
241 delete aDestination; |
|
242 } |
|
243 } |
|
244 else |
|
245 { // this is a new destination which hasn't been updated yet |
|
246 // there may be more than one dest with id 0 -> must search by |
|
247 // iDestinationItem |
|
248 for (TInt index = 0; index < iDestinationArray.Count(); index++) |
|
249 { |
|
250 if ( iDestinationArray[index].iDestinationItem == |
|
251 aDestination ) |
|
252 { |
|
253 aDestination->DecrementRefCounter(); |
|
254 if (!aDestination->GetRefCounter()) |
|
255 {// this was the last reference -> must delete |
|
256 iDestinationArray.Remove(index); |
|
257 delete aDestination; |
|
258 } |
|
259 break; |
|
260 } |
|
261 } |
|
262 } |
|
263 } |
|
264 |
|
265 void CCMObjectPool::RemoveDestination( CCmDestinationImpl* aDestination ) |
|
266 { |
|
267 RemoveDestination(aDestination->GetData()); |
|
268 aDestination->SetData(NULL); |
|
269 } |
|
270 |
|
271 void CCMObjectPool::DestinationUpdated( CCmDestinationImpl* aDestination ) |
|
272 { |
|
273 // there may be more than one dest with id 0 -> must search by |
|
274 // iDestinationItem |
|
275 for (TInt index = 0; index < iDestinationArray.Count(); index++) |
|
276 { |
|
277 if ( iDestinationArray[index].iDestinationItem == |
|
278 aDestination->GetData() ) |
|
279 { |
|
280 if (aDestination->IdIsValid()) break; //allready updated |
|
281 iDestinationArray[index].iDestinationId = aDestination->Id(); |
|
282 iDestinationArray.SortUnsigned(); |
|
283 break; |
|
284 } |
|
285 } |
|
286 } |
|
287 |
|
288 void CCMObjectPool::ConnMethodUpdatedL( CCmPluginBaseEng* aCM ) |
|
289 { |
|
290 // there may be more than one dest with id 0 -> must search by |
|
291 // iDestinationItem |
|
292 for (TInt index = 0; index < iConnectionMethodArray.Count(); index++) |
|
293 { |
|
294 if ( iConnectionMethodArray[index].iConnectionMethodItem == |
|
295 aCM ) |
|
296 { |
|
297 TInt cmId = aCM->GetIntAttributeL(CMManager::ECmId); |
|
298 iConnectionMethodArray[index].iConnectionMethodId = cmId; |
|
299 iConnectionMethodArray.SortUnsigned(); |
|
300 break; |
|
301 } |
|
302 } |
|
303 } |
|
304 |
|
305 void CCMObjectPool::RemoveConnectionMethodL( CCmPluginBase* aCM) |
|
306 { |
|
307 RemoveConnectionMethodL(aCM->Plugin()); |
|
308 aCM->SetPlugin(NULL); |
|
309 } |
|
310 |
|
311 void CCMObjectPool::RemoveConnectionMethodL( CCmPluginBaseEng* aCM) |
|
312 { |
|
313 if (aCM->IdIsValid()) |
|
314 { |
|
315 aCM->DecrementRefCounter(); |
|
316 if (!aCM->GetRefCounter()) |
|
317 {// this was the last reference -> must delete |
|
318 TUint32 cmId = aCM->GetIntAttributeL(CMManager::ECmId); |
|
319 TObjectPoolCMItem findD( NULL, cmId ); |
|
320 TInt index = iConnectionMethodArray.FindInUnsignedKeyOrder(findD); |
|
321 iConnectionMethodArray.Remove(index); |
|
322 delete aCM; |
|
323 } |
|
324 } |
|
325 else |
|
326 { // this is a new cm which hasn't been updated yet |
|
327 // there may be more than one cm with id 0 -> must search by pointer |
|
328 for (TInt index = 0; index < iConnectionMethodArray.Count(); index++) |
|
329 { |
|
330 if ( iConnectionMethodArray[index].iConnectionMethodItem == aCM ) |
|
331 { |
|
332 aCM->DecrementRefCounter(); |
|
333 if (!aCM->GetRefCounter()) |
|
334 {// this was the last reference -> must delete |
|
335 iConnectionMethodArray.Remove(index); |
|
336 delete aCM; |
|
337 } |
|
338 break; |
|
339 } |
|
340 } |
|
341 } |
|
342 } |
|
343 |
|