|
1 // Copyright (c) 2004-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 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalTechnology |
|
19 */ |
|
20 |
|
21 #include <ecom/ecom.h> |
|
22 #include <elements/metadata.h> |
|
23 #include <elements/metatype.h> |
|
24 #include <elements/metaiterator.h> |
|
25 |
|
26 |
|
27 #ifdef _DEBUG |
|
28 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
29 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
30 _LIT(KSpecAssert_ElemNetMetaMtDt, "ElemNetMetaMtDt."); |
|
31 #endif |
|
32 |
|
33 // Maximum size of the MMetaType based object in terms of sizeof(TAny*). |
|
34 // KMMetaTypeMaxSize * sizeof(TAny*) is the size of the memory reserved |
|
35 // on the stack for the in-place instantiation. |
|
36 const TInt KMMetaTypeMaxSize = 10; |
|
37 |
|
38 |
|
39 using namespace Meta; |
|
40 |
|
41 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT |
|
42 EXPORT_C STypeId STypeId::CreateSTypeId(TPtrC8& aDes) |
|
43 { |
|
44 // check no padding, so no alignment worries in copying single block |
|
45 STypeId id; |
|
46 __ASSERT_COMPILE(sizeof(STypeId) == sizeof(id.iUid) + sizeof(id.iType)); |
|
47 |
|
48 Mem::Copy(&id, aDes.Ptr(), sizeof(STypeId)); |
|
49 |
|
50 // trim typeid from front of store |
|
51 aDes.Set(aDes.Ptr() + sizeof(STypeId), aDes.Length() - sizeof(STypeId)); |
|
52 return id; |
|
53 } |
|
54 #endif |
|
55 |
|
56 EXPORT_C TInt STypeId::Check( TPtrC8& aDes ) const |
|
57 { |
|
58 if (aDes.Length() < (TInt)sizeof(STypeId)) |
|
59 { |
|
60 return KErrArgument; |
|
61 } |
|
62 STypeId typeId; |
|
63 Mem::Copy(&typeId, aDes.Ptr(), sizeof(STypeId)); |
|
64 TInt error = KErrArgument; |
|
65 if ( *this == typeId ) |
|
66 {//update pointer (type) only if the type matches |
|
67 aDes.Set(aDes.Ptr()+sizeof(STypeId),aDes.Length()-sizeof(STypeId)); |
|
68 error = KErrNone; |
|
69 } |
|
70 return error; |
|
71 } |
|
72 |
|
73 EXPORT_C SMetaData::SMetaData() |
|
74 /** |
|
75 * Protected and explicit constructor |
|
76 */ |
|
77 { |
|
78 } |
|
79 |
|
80 EXPORT_C SMetaData::~SMetaData() |
|
81 /** |
|
82 * Virtual destructor |
|
83 */ |
|
84 { |
|
85 } |
|
86 |
|
87 EXPORT_C TInt SMetaData::CheckTypeOf( TPtrC8& aDes ) const |
|
88 { |
|
89 if (aDes.Length() < (TInt)sizeof(STypeId)) |
|
90 { |
|
91 return KErrArgument; |
|
92 } |
|
93 STypeId typeId; |
|
94 Mem::Copy(&typeId, aDes.Ptr(), sizeof(STypeId)); |
|
95 TInt error = KErrArgument; |
|
96 if ( IsTypeOf(typeId) ) |
|
97 {//update pointer (type) only if the type matches |
|
98 aDes.Set(aDes.Ptr()+sizeof(STypeId),aDes.Length()-sizeof(STypeId)); |
|
99 error = KErrNone; |
|
100 } |
|
101 return error; |
|
102 } |
|
103 |
|
104 EXPORT_C STypeId SMetaData::GetTypeId() const |
|
105 { |
|
106 const SVDataTableEntry* entry = GetVDataTable(); |
|
107 __ASSERT_DEBUG( entry , User::Panic(KSpecAssert_ElemNetMetaMtDt, 1)); |
|
108 return STypeId::CreateSTypeId( entry->iOffset, reinterpret_cast<TInt32>(entry->iMetaNewL) ); |
|
109 } |
|
110 |
|
111 EXPORT_C TInt SMetaData::IsTypeOf( const STypeId& aTypeId ) const |
|
112 { |
|
113 const SVDataTableEntry* entry = GetVDataTable(); |
|
114 __ASSERT_DEBUG( entry , User::Panic(KSpecAssert_ElemNetMetaMtDt, 2)); |
|
115 for(;;) |
|
116 { |
|
117 STypeId typeId = { entry->iOffset, reinterpret_cast<TInt32>(entry->iMetaNewL) }; |
|
118 if ( typeId == aTypeId ) |
|
119 { |
|
120 return 1; |
|
121 } |
|
122 //move through the table |
|
123 while ( (++entry)->iMetaNewL ) {;} |
|
124 if ( !entry->iOffset ) |
|
125 { |
|
126 break; |
|
127 } |
|
128 typedef SVDataTableEntry* (*TMetaBaseTableNewL)(); |
|
129 entry = reinterpret_cast<TMetaBaseTableNewL>(entry->iOffset)(); |
|
130 } |
|
131 return 0; |
|
132 } |
|
133 |
|
134 EXPORT_C void SMetaData::Copy(const SMetaData& aSource) |
|
135 /** |
|
136 * Copies values of a SMetaData object's properties into properties of *this. |
|
137 * Both meta objects are of the same type. |
|
138 */ |
|
139 { |
|
140 __ASSERT_DEBUG(GetTypeId()==aSource.GetTypeId(),User::Panic(_L("SMetaData"),KErrArgument)); |
|
141 |
|
142 TAny* mem[KMMetaTypeMaxSize]; |
|
143 TMetaVTableIterator attribIter(this); |
|
144 SVDataTableEntry const* entry; |
|
145 while ((entry = attribIter++) != NULL) |
|
146 { |
|
147 MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset)); |
|
148 metaType->Copy(aSource.GetAttribPtr(entry->iOffset)); |
|
149 } |
|
150 } |
|
151 |
|
152 EXPORT_C TInt SMetaData::Store(TDes8& aDes) const |
|
153 /** |
|
154 * Stores the meta object into a descriptor |
|
155 */ |
|
156 { |
|
157 const STypeId& typeId = GetTypeId(); |
|
158 TInt len = Length(); |
|
159 |
|
160 if ((aDes.MaxLength()-aDes.Length()) < len) |
|
161 { |
|
162 return KErrOverflow; |
|
163 } |
|
164 |
|
165 aDes.Append((TUint8*)&typeId,sizeof(STypeId)); //store TID |
|
166 aDes.Append((TUint8*)&len,sizeof(TInt32)); //store length |
|
167 |
|
168 TAny* mem[KMMetaTypeMaxSize]; |
|
169 TMetaVTableIterator attribIter(this); |
|
170 SVDataTableEntry const* entry; |
|
171 while ((entry = attribIter++) != NULL) |
|
172 { |
|
173 MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset)); |
|
174 TInt ret = metaType->Store(aDes); |
|
175 if (ret != KErrNone) |
|
176 { |
|
177 return ret; |
|
178 } |
|
179 } |
|
180 return KErrNone; |
|
181 } |
|
182 |
|
183 EXPORT_C TInt SMetaData::Check(TPtrC8& aDes) const |
|
184 { |
|
185 return GetTypeId().Check(aDes); |
|
186 } |
|
187 |
|
188 EXPORT_C TInt SMetaData::Load(TPtrC8& aDes) |
|
189 /** |
|
190 * Loads the meta object from a descriptor |
|
191 */ |
|
192 { |
|
193 if (aDes.Length() < (TInt)sizeof(TInt32)) |
|
194 { |
|
195 return KErrArgument; |
|
196 } |
|
197 |
|
198 TUint32 length; |
|
199 Mem::Copy(&length, aDes.Ptr(), sizeof(TUint32)); |
|
200 aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (type) |
|
201 |
|
202 if (length > aDes.Length() + sizeof(TUint32) + sizeof(STypeId)) |
|
203 { |
|
204 return KErrArgument; |
|
205 } |
|
206 |
|
207 TAny* mem[KMMetaTypeMaxSize]; |
|
208 TMetaVTableIterator attribIter(this); |
|
209 SVDataTableEntry const* entry; |
|
210 while ((entry = attribIter++) != NULL) |
|
211 { |
|
212 //xxx This isn't a leaving function! It should be New not NewL |
|
213 MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset)); |
|
214 TInt ret = metaType->Load(aDes); |
|
215 if (ret != KErrNone) |
|
216 { |
|
217 return ret; |
|
218 } |
|
219 } |
|
220 return KErrNone; |
|
221 } |
|
222 |
|
223 EXPORT_C TInt SMetaData::Length() const |
|
224 /** |
|
225 * Returns length of the object excluding TID and stored length fields |
|
226 */ |
|
227 { |
|
228 TInt length = sizeof(STypeId) + sizeof(TInt32); |
|
229 TAny* mem[KMMetaTypeMaxSize]; |
|
230 TMetaVTableIterator attribIter(this); |
|
231 SVDataTableEntry const* entry; |
|
232 while ((entry = attribIter++) != NULL) |
|
233 { |
|
234 MMetaType* metaType = entry->iMetaNewL(mem,GetAttribPtr(entry->iOffset)); |
|
235 length += metaType->Length(); |
|
236 } |
|
237 return length; |
|
238 } |
|
239 |
|
240 using Meta::SMetaDataECom; |
|
241 |
|
242 EXPORT_C SMetaDataECom::SMetaDataECom() |
|
243 /** |
|
244 * Protected and explicit constructor |
|
245 */ |
|
246 { |
|
247 iDestroyUid.iUid = 0; |
|
248 } |
|
249 |
|
250 EXPORT_C SMetaDataECom::~SMetaDataECom() |
|
251 /** |
|
252 * Destructor |
|
253 */ |
|
254 { |
|
255 if ( iDestroyUid.iUid ) |
|
256 { |
|
257 REComSession::DestroyedImplementation(iDestroyUid); |
|
258 } |
|
259 } |
|
260 |
|
261 EXPORT_C SMetaDataECom* SMetaDataECom::LoadL(TPtrC8& aDes) |
|
262 /** |
|
263 * Static, encapsulates instantiation and loading of a content of a meta object |
|
264 * from data contained in a descriptor. |
|
265 * This function must be provided by all meta objects that will be used as a parameter |
|
266 * to TMetaPtr<> template. |
|
267 */ |
|
268 { |
|
269 if (aDes.Length() < (3 * (TInt) sizeof(TInt32))) |
|
270 { |
|
271 // Fatal error, descriptor is corrupt |
|
272 User::Leave(KErrArgument); |
|
273 } |
|
274 |
|
275 // Extract UID and type |
|
276 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT |
|
277 STypeId typeId = STypeId::CreateSTypeId(aDes); |
|
278 #else |
|
279 STypeId typeId; |
|
280 Mem::Copy(&typeId.iUid, aDes.Ptr(), sizeof(TUid)); |
|
281 aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (uid) |
|
282 Mem::Copy(&typeId.iType, aDes.Ptr(), sizeof(TInt32)); |
|
283 aDes.Set(aDes.Ptr()+sizeof(TUint32),aDes.Length()-sizeof(TUint32)); //update pointer (type) |
|
284 #endif |
|
285 |
|
286 // Attempt to load the object |
|
287 SMetaDataECom* mtd = NULL; |
|
288 TRAPD(ret, mtd = NewInstanceL(typeId)); |
|
289 |
|
290 if (ret != KErrNone) |
|
291 { |
|
292 if (ret == KErrNotFound) |
|
293 { |
|
294 // Attempt to move the pointer on |
|
295 TUint32 len; |
|
296 Mem::Copy(&len, aDes.Ptr(), sizeof(TUint32)); |
|
297 if (len <= (TUint32) aDes.Length()) |
|
298 { |
|
299 aDes.Set(aDes.Ptr()+len,aDes.Length()-len); //update pointer (type) |
|
300 } |
|
301 else |
|
302 { |
|
303 aDes.Set(aDes.Right(0)); |
|
304 } |
|
305 } |
|
306 User::Leave(ret); |
|
307 } |
|
308 |
|
309 CleanupDeletePushL(mtd); |
|
310 |
|
311 // Ask the object to de-marshall its data |
|
312 ret = mtd->Load(aDes); |
|
313 if (ret != KErrNone) |
|
314 { |
|
315 User::Leave(ret); |
|
316 } |
|
317 CleanupStack::Pop(mtd); |
|
318 return mtd; |
|
319 } |
|
320 |
|
321 EXPORT_C SMetaDataECom* SMetaDataECom::NewInstanceL(const STypeId& aTypeId) |
|
322 /** |
|
323 * Static, instantiates a meta object based on its Type ID. |
|
324 */ |
|
325 { |
|
326 TUid destroyUid; |
|
327 SMetaDataECom* obj = reinterpret_cast<SMetaDataECom*>(REComSession::CreateImplementationL(aTypeId.iUid, destroyUid, (TAny*)aTypeId.iType)); |
|
328 obj->iDestroyUid = destroyUid; |
|
329 return obj; |
|
330 } |
|
331 |
|
332 |