|
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // ss_cmetaextensioncontainer.cpp |
|
15 // |
|
16 |
|
17 |
|
18 #include "ss_cmetaextensioncontainer.h" |
|
19 #include <comms-infras/ss_log.h> |
|
20 |
|
21 using namespace ESock; |
|
22 |
|
23 const TInt KReservedContainerSlots = 4; |
|
24 const TInt KReservedExtensionSlots = 4; |
|
25 |
|
26 |
|
27 |
|
28 // =========================================================== |
|
29 // CMetaExtensionContainerImplBase |
|
30 // =========================================================== |
|
31 |
|
32 void CMetaExtensionContainerImplBase::DeletePtr() |
|
33 { |
|
34 } |
|
35 |
|
36 const Meta::SMetaData& CMetaExtensionContainerImplBase::FindExtensionL(const Meta::STypeId& aTypeId) const |
|
37 { |
|
38 const Meta::SMetaData* ext = FindExtension(aTypeId); |
|
39 if (!ext) |
|
40 { |
|
41 User::Leave(KErrNotFound); |
|
42 } |
|
43 return *ext; |
|
44 } |
|
45 |
|
46 |
|
47 |
|
48 // =========================================================== |
|
49 // CMetaExtensionContainer |
|
50 // =========================================================== |
|
51 |
|
52 CMetaExtensionContainer* CMetaExtensionContainer::NewLC(const CMetaExtensionContainerImplBase* aBaseContainer) |
|
53 { |
|
54 CMetaExtensionContainer* self = new(ELeave)CMetaExtensionContainer(); |
|
55 CleanupStack::PushL(self); |
|
56 LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::NewLC() - [this=%x] [baseContainer=%x]"), self, aBaseContainer)); |
|
57 self->ConstructL(aBaseContainer); |
|
58 return self; |
|
59 } |
|
60 |
|
61 |
|
62 CMetaExtensionContainer::~CMetaExtensionContainer() |
|
63 { |
|
64 iExtensions.ResetAndDestroy(); |
|
65 iExtensions.Close(); |
|
66 |
|
67 #ifndef MEC_UNITTEST |
|
68 LOG_NODE_DESTROY(KESockComponentTag, CMetaExtensionContainer); |
|
69 #endif |
|
70 } |
|
71 |
|
72 CMetaExtensionContainer::CMetaExtensionContainer() |
|
73 : CMetaExtensionContainerImplBase(EMetaExtensionContainer) |
|
74 { |
|
75 #ifndef MEC_UNITTEST |
|
76 LOG_NODE_CREATE(KESockComponentTag, CMetaExtensionContainer); |
|
77 #endif |
|
78 } |
|
79 |
|
80 |
|
81 void CMetaExtensionContainer::ConstructL(const CMetaExtensionContainerImplBase* aBaseContainer) |
|
82 { |
|
83 iExtensions.ReserveL(KReservedExtensionSlots); |
|
84 if (aBaseContainer) |
|
85 { |
|
86 SetBaseContainer(aBaseContainer); |
|
87 } |
|
88 } |
|
89 |
|
90 |
|
91 void CMetaExtensionContainer::DeletePtr() |
|
92 { |
|
93 // Releasing references to any base containers |
|
94 if (iBaseContainer) |
|
95 { |
|
96 const_cast<CMetaExtensionContainerImplBase*>(iBaseContainer)->Close(); |
|
97 iBaseContainer = NULL; |
|
98 } |
|
99 } |
|
100 |
|
101 |
|
102 const CMetaExtensionContainerImplBase* CMetaExtensionContainer::BaseContainer() const |
|
103 { |
|
104 return iBaseContainer; |
|
105 } |
|
106 |
|
107 |
|
108 void CMetaExtensionContainer::SetBaseContainer(const CMetaExtensionContainerImplBase* aBaseContainer) |
|
109 { |
|
110 ASSERT(aBaseContainer); |
|
111 ASSERT(!iBaseContainer); |
|
112 const_cast<CMetaExtensionContainerImplBase*>(aBaseContainer)->Open(); |
|
113 iBaseContainer = aBaseContainer; |
|
114 } |
|
115 |
|
116 |
|
117 void CMetaExtensionContainer::RemoveBaseContainer() |
|
118 { |
|
119 // Only call this if the cleanup checks have been done and it makes sense |
|
120 ASSERT(iBaseContainer && iBaseContainer->Type() == EMetaExtensionContainer); |
|
121 |
|
122 const CMetaExtensionContainer* oldBaseMecImpl = static_cast<const CMetaExtensionContainer*>(iBaseContainer); |
|
123 const CMetaExtensionContainerImplBase* newBaseMecImpl = oldBaseMecImpl->iBaseContainer; |
|
124 if (newBaseMecImpl) |
|
125 { |
|
126 // Do this before assigning iBaseContainer to ensure the reference is there |
|
127 // to hold it open |
|
128 const_cast<CMetaExtensionContainerImplBase*>(newBaseMecImpl)->Open(); |
|
129 } |
|
130 iBaseContainer = newBaseMecImpl; |
|
131 const_cast<CMetaExtensionContainer*>(oldBaseMecImpl)->Close(); |
|
132 } |
|
133 |
|
134 |
|
135 const Meta::SMetaData* CMetaExtensionContainer::FindExtension(const Meta::STypeId& aTypeId) const |
|
136 { |
|
137 const Meta::SMetaData* ext = FindExtensionInThisContainer(aTypeId); |
|
138 |
|
139 if (!ext && BaseContainer()) |
|
140 { |
|
141 ext = BaseContainer()->FindExtension(aTypeId); |
|
142 } |
|
143 |
|
144 return ext; |
|
145 } |
|
146 |
|
147 |
|
148 const Meta::SMetaData* CMetaExtensionContainer::FindExtensionInThisContainer(const Meta::STypeId& aTypeId) const |
|
149 { |
|
150 TInt length = iExtensions.Count(); |
|
151 for (TUint i = 0; i < length; ++i) |
|
152 { |
|
153 if (iExtensions[i]->Object()->GetTypeId() == aTypeId) |
|
154 { |
|
155 return iExtensions[i]->Object(); |
|
156 } |
|
157 } |
|
158 |
|
159 return NULL; |
|
160 } |
|
161 |
|
162 |
|
163 |
|
164 TInt CMetaExtensionContainer::AppendExtension(const Meta::SMetaData* aExtension) |
|
165 { |
|
166 TRAPD(err, AppendExtensionL(aExtension)); |
|
167 return err; |
|
168 } |
|
169 |
|
170 |
|
171 void CMetaExtensionContainer::AppendExtensionL(const Meta::SMetaData* aExtension) |
|
172 { |
|
173 if (aExtension == NULL) |
|
174 { |
|
175 LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - NULL extension pointer [this=%x]"), this)); |
|
176 User::Leave(KErrArgument); |
|
177 } |
|
178 |
|
179 if (FindExtensionInThisContainer(aExtension->GetTypeId()) != NULL) |
|
180 { |
|
181 LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - duplicate extension (%08x) ID %x:%x added [this=%x]"), |
|
182 aExtension, aExtension->GetTypeId().iUid.iUid, aExtension->GetTypeId().iType, this)); |
|
183 |
|
184 #if defined(_DEBUG) && !defined(MEC_UNITTEST) |
|
185 _LIT(KMECPanic, "esockmec"); |
|
186 //Included in DEBUG mode as extension should not be added if already part of iExtensions |
|
187 //Brings attention to coding error that should be fixed before release. |
|
188 __ASSERT_DEBUG(EFalse, User::Panic(KMECPanic(), 0)); |
|
189 #endif |
|
190 |
|
191 User::Leave(KErrAlreadyExists); |
|
192 } |
|
193 |
|
194 Meta::TMetaDataDeAllocator* deallocator = Meta::TMetaDataDeAllocator::NewLC(aExtension); |
|
195 TInt ret = iExtensions.Append(deallocator); |
|
196 if(KErrNone != ret) |
|
197 { |
|
198 deallocator->LeaveObject(); |
|
199 User::Leave(ret); |
|
200 } |
|
201 |
|
202 LOG(ESockLog::Printf(_L8("CMetaExtensionContainer::AppendExtensionL() - extension (%08x) ID %x:%x added [this=%x]"), |
|
203 aExtension, aExtension->GetTypeId().iUid.iUid, aExtension->GetTypeId().iType, this)); |
|
204 |
|
205 CleanupStack::Pop(deallocator); |
|
206 } |
|
207 |
|
208 |
|
209 void CMetaExtensionContainer::Compact() |
|
210 { |
|
211 const CMetaExtensionContainer* baseMecImpl = NULL; |
|
212 |
|
213 while (baseMecImpl != BaseContainer()) |
|
214 { |
|
215 // We have a base container, and its the first time through the loop |
|
216 // or its not the same as the last execution of the loop |
|
217 baseMecImpl = static_cast<const CMetaExtensionContainer*>(BaseContainer()); |
|
218 |
|
219 if (!baseMecImpl || baseMecImpl->Type() != EMetaExtensionContainer |
|
220 || baseMecImpl->iExtensions.Count() > iExtensions.Count()) |
|
221 { |
|
222 // There is no base container, OR the base container isn't an extension |
|
223 // container implementation, OR the immediate base container holds |
|
224 // more extensions than this container does and it cannot be removed |
|
225 // since there is no way this container can be overriding all of them. |
|
226 return; |
|
227 } |
|
228 |
|
229 // Check if all of the base container extensions are overridden by ours |
|
230 TInt count = baseMecImpl->iExtensions.Count(); |
|
231 Meta::STypeId typeId; |
|
232 for (TInt i=0; i<count; i++) |
|
233 { |
|
234 typeId = baseMecImpl->iExtensions[i]->Object()->GetTypeId(); |
|
235 const Meta::SMetaData* ext = FindExtensionInThisContainer(typeId); |
|
236 if (!ext) |
|
237 { |
|
238 // Not all of the extensions in the base container are overridden |
|
239 return; |
|
240 } |
|
241 } |
|
242 |
|
243 // If we made it here this container overrides all of the extensions in the |
|
244 // immediate base container. We can remove it from our chain. |
|
245 RemoveBaseContainer(); |
|
246 } |
|
247 } |
|
248 |
|
249 |
|
250 // =========================================================== |
|
251 // CMetaExtensionContainerArray |
|
252 // =========================================================== |
|
253 |
|
254 CMetaExtensionContainerArray* CMetaExtensionContainerArray::NewLC(const CMetaExtensionContainerImplBase* aBaseContainer) |
|
255 { |
|
256 CMetaExtensionContainerArray* self = new(ELeave)CMetaExtensionContainerArray(); |
|
257 CleanupStack::PushL(self); |
|
258 LOG(ESockLog::Printf(_L8("CMetaExtensionContainerArray::NewLC() - [this=%x] [baseContainer=%x]"), self, aBaseContainer)); |
|
259 self->ConstructL(aBaseContainer); |
|
260 return self; |
|
261 } |
|
262 |
|
263 |
|
264 CMetaExtensionContainerArray::~CMetaExtensionContainerArray() |
|
265 { |
|
266 iContainers.Close(); |
|
267 |
|
268 #ifndef MEC_UNITTEST |
|
269 LOG_NODE_DESTROY(KESockComponentTag, CMetaExtensionContainerArray); |
|
270 #endif |
|
271 } |
|
272 |
|
273 |
|
274 CMetaExtensionContainerArray::CMetaExtensionContainerArray() |
|
275 : CMetaExtensionContainerImplBase(EMetaExtensionContainerArray) |
|
276 { |
|
277 #ifndef MEC_UNITTEST |
|
278 LOG_NODE_CREATE(KESockComponentTag, CMetaExtensionContainerArray); |
|
279 #endif |
|
280 } |
|
281 |
|
282 |
|
283 void CMetaExtensionContainerArray::ConstructL(const CMetaExtensionContainerImplBase* aBaseContainer) |
|
284 { |
|
285 iContainers.ReserveL(KReservedContainerSlots); |
|
286 if (aBaseContainer) |
|
287 { |
|
288 iContainers.AppendL(aBaseContainer); |
|
289 const_cast<CMetaExtensionContainerImplBase*>(aBaseContainer)->Open(); |
|
290 } |
|
291 } |
|
292 |
|
293 |
|
294 void CMetaExtensionContainerArray::DeletePtr() |
|
295 { |
|
296 TInt i = iContainers.Count(); |
|
297 while (i--) |
|
298 { |
|
299 const_cast<CMetaExtensionContainerImplBase*>(iContainers[i])->Close(); |
|
300 } |
|
301 } |
|
302 |
|
303 |
|
304 const Meta::SMetaData* CMetaExtensionContainerArray::FindExtension(const Meta::STypeId& aTypeId) const |
|
305 { |
|
306 const Meta::SMetaData* ext = NULL; |
|
307 |
|
308 TInt i = iContainers.Count(); |
|
309 while (!ext && i--) |
|
310 { |
|
311 ext = iContainers[i]->FindExtension(aTypeId); |
|
312 } |
|
313 |
|
314 return ext; |
|
315 } |
|
316 |
|
317 |
|
318 TInt CMetaExtensionContainerArray::AppendContainer(const CMetaExtensionContainerImplBase& aContainer) |
|
319 { |
|
320 TInt length = iContainers.Count(); |
|
321 for (TUint i = 0; i < length; ++i) |
|
322 { |
|
323 if (iContainers[i] == &aContainer) |
|
324 { |
|
325 return KErrAlreadyExists; |
|
326 } |
|
327 } |
|
328 |
|
329 TInt err = iContainers.Append(&aContainer); |
|
330 if (err == KErrNone) |
|
331 { |
|
332 // Add a reference to the container |
|
333 const_cast<CMetaExtensionContainerImplBase&>(aContainer).Open(); |
|
334 } |
|
335 return err; |
|
336 } |
|
337 |
|
338 |
|
339 |
|
340 |