|
1 // Copyright (c) 2006-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 @publishedPartner |
|
19 */ |
|
20 |
|
21 #include <mtp/cmtptypeobjectpropdesc.h> |
|
22 #include <mtp/cmtptypeinterdependentpropdesc.h> |
|
23 #include <mtp/mtpdatatypeconstants.h> |
|
24 |
|
25 #include "mtpdatatypespanic.h" |
|
26 |
|
27 // Dataset constants |
|
28 const TUint CMTPTypeInterdependentPropDesc::KNumberOfInterdependenciesChunk(0); |
|
29 const TUint CMTPTypeInterdependentPropDesc::KInterdependentPropertiesChunks(1); |
|
30 |
|
31 const TUint CMTPTypeInterdependentProperties::KNumberOfPropDescsChunk(0); |
|
32 const TUint CMTPTypeInterdependentProperties::KObjectPropDescChunks(1); |
|
33 |
|
34 /** |
|
35 MTP InterdependentPropDesc dataset factory method. This method is used to create an |
|
36 empty MTP InterdependentPropDesc dataset. |
|
37 @return A pointer to the MTP InterdependentPropDesc dataset type. Ownership IS |
|
38 transfered. |
|
39 @leave One of the system wide error codes, if unsuccessful. |
|
40 */ |
|
41 EXPORT_C CMTPTypeInterdependentPropDesc* CMTPTypeInterdependentPropDesc::NewL() |
|
42 { |
|
43 CMTPTypeInterdependentPropDesc* self = CMTPTypeInterdependentPropDesc::NewLC(); |
|
44 CleanupStack::Pop(self); |
|
45 return self; |
|
46 } |
|
47 |
|
48 /** |
|
49 MTP InterdependentPropDesc dataset factory method. This method is used to create an |
|
50 empty MTP InterdependentPropDesc dataset. A pointer to the data type is placed on the |
|
51 cleanup stack. |
|
52 @return A pointer to the MTP InterdependentPropDesc dataset type. Ownership IS |
|
53 transfered. |
|
54 @leave One of the system wide error codes, if unsuccessful. |
|
55 */ |
|
56 EXPORT_C CMTPTypeInterdependentPropDesc* CMTPTypeInterdependentPropDesc::NewLC() |
|
57 { |
|
58 CMTPTypeInterdependentPropDesc* self = new(ELeave) CMTPTypeInterdependentPropDesc(); |
|
59 CleanupStack::PushL(self); |
|
60 self->ConstructL(); |
|
61 return self; |
|
62 } |
|
63 |
|
64 /** |
|
65 Destructor. |
|
66 */ |
|
67 EXPORT_C CMTPTypeInterdependentPropDesc::~CMTPTypeInterdependentPropDesc() |
|
68 { |
|
69 iChunksInterdependentProperties.ResetAndDestroy(); |
|
70 } |
|
71 |
|
72 /** |
|
73 Appends the specified InterdependentPropDesc value quadruple to the InterdependentPropDesc. |
|
74 Ownership of the specified InterdependentPropDesc value quadruple is passed to the |
|
75 InterdependentPropDesc. |
|
76 @param aElement The InterdependentPropDesc value quadruple to append. Ownership IS |
|
77 transferred. |
|
78 @leave One of the system wide error codes, if unsuccessful. |
|
79 */ |
|
80 EXPORT_C void CMTPTypeInterdependentPropDesc::AppendL(CMTPTypeInterdependentProperties* aInterdependentProperties) |
|
81 { |
|
82 // Increment NumberOfElements. |
|
83 const TUint index(iChunkNumberOfInterdependencies.Value()); |
|
84 iChunkNumberOfInterdependencies.Set(index + 1); |
|
85 |
|
86 // Append the element. |
|
87 AppendElementChunkL(aInterdependentProperties); |
|
88 } |
|
89 |
|
90 /** |
|
91 Provides the NumberOfElements element value. |
|
92 */ |
|
93 EXPORT_C TUint32 CMTPTypeInterdependentPropDesc::NumberOfInterdependencies() const |
|
94 { |
|
95 return iChunkNumberOfInterdependencies.Value(); |
|
96 } |
|
97 |
|
98 /** |
|
99 Provides a non-const reference to the InterdependentPropDesc value quadruple element at |
|
100 the specified index. |
|
101 @param aIndex The index of the required element. |
|
102 @param aValue On successful completion, a non-const reference to the requested |
|
103 element. |
|
104 @leave One of the system wide error codes, if unsuccessful. |
|
105 */ |
|
106 EXPORT_C CMTPTypeInterdependentProperties& CMTPTypeInterdependentPropDesc::InterdependentProperties(TUint aIndex) const |
|
107 { |
|
108 return *iChunksInterdependentProperties[aIndex]; |
|
109 } |
|
110 |
|
111 EXPORT_C TInt CMTPTypeInterdependentPropDesc::FirstWriteChunk(TPtr8& aChunk) |
|
112 { |
|
113 /* |
|
114 Reset the type in preparation for the data stream, by deleting all |
|
115 except the first chunk. |
|
116 */ |
|
117 for (TUint i(ChunkCount() - 1); (i >= (KNumberOfInterdependenciesChunk + 1)); i--) |
|
118 { |
|
119 ChunkRemove(i); |
|
120 } |
|
121 iChunksInterdependentProperties.ResetAndDestroy(); |
|
122 |
|
123 // Setup the write chunk pointer. |
|
124 TInt err(UpdateWriteSequenceErr(CMTPTypeCompoundBase::FirstWriteChunk(aChunk))); |
|
125 switch (err) |
|
126 { |
|
127 case KMTPChunkSequenceCompletion: |
|
128 err = KErrNone; |
|
129 // Don't break, fall through to set the write sequence state. |
|
130 |
|
131 case KErrNone: |
|
132 // Set the write sequence state. |
|
133 iWriteSequenceState = EInProgress; |
|
134 break; |
|
135 |
|
136 default: |
|
137 break; |
|
138 } |
|
139 |
|
140 return err; |
|
141 } |
|
142 |
|
143 EXPORT_C TInt CMTPTypeInterdependentPropDesc::NextWriteChunk(TPtr8& aChunk) |
|
144 { |
|
145 TInt err(KMTPChunkSequenceCompletion); |
|
146 |
|
147 if (iWriteSequenceState != EIdle) |
|
148 { |
|
149 err = UpdateWriteSequenceErr(CMTPTypeCompoundBase::NextWriteChunk(aChunk)); |
|
150 if ((iWriteSequenceErr == KMTPChunkSequenceCompletion) && (iWriteSequenceState != EIdle)) |
|
151 { |
|
152 err = KErrNone; |
|
153 } |
|
154 } |
|
155 return err; |
|
156 |
|
157 } |
|
158 |
|
159 EXPORT_C TUint CMTPTypeInterdependentPropDesc::Type() const |
|
160 { |
|
161 return EMTPTypeInterdependentPropDescDataset; |
|
162 } |
|
163 |
|
164 EXPORT_C TBool CMTPTypeInterdependentPropDesc::CommitRequired() const |
|
165 { |
|
166 return ETrue; |
|
167 } |
|
168 |
|
169 EXPORT_C MMTPType* CMTPTypeInterdependentPropDesc::CommitChunkL(TPtr8& aChunk) |
|
170 { |
|
171 if (iWriteSequenceErr == KMTPChunkSequenceCompletion) |
|
172 { |
|
173 switch (iWriteSequenceState) |
|
174 { |
|
175 case EInProgress: |
|
176 if ((iChunkNumberOfInterdependencies.Value()) && |
|
177 (iChunksInterdependentProperties.Count() < iChunkNumberOfInterdependencies.Value())) |
|
178 { |
|
179 // Allocate the next element chunk. |
|
180 CMTPTypeInterdependentProperties* element = CMTPTypeInterdependentProperties::NewLC(); |
|
181 AppendElementChunkL(element); |
|
182 CleanupStack::Pop(element); |
|
183 } |
|
184 else |
|
185 { |
|
186 iWriteSequenceState = EIdle; |
|
187 } |
|
188 break; |
|
189 |
|
190 case EIdle: |
|
191 // Completing the last element in the write sequence. |
|
192 break; |
|
193 |
|
194 default: |
|
195 Panic(EMTPTypeBadStorage); |
|
196 break; |
|
197 } |
|
198 } |
|
199 |
|
200 if (CMTPTypeCompoundBase::CommitRequired()) |
|
201 { |
|
202 CMTPTypeCompoundBase::CommitChunkL(aChunk); |
|
203 } |
|
204 return NULL; |
|
205 } |
|
206 |
|
207 const CMTPTypeCompoundBase::TElementInfo& CMTPTypeInterdependentPropDesc::ElementInfo(TInt aElementId) const |
|
208 { |
|
209 if (aElementId == KNumberOfInterdependenciesChunk) |
|
210 { |
|
211 return iInfoNumberOfInterdependencies; |
|
212 } |
|
213 else |
|
214 { |
|
215 __ASSERT_ALWAYS(((aElementId - KInterdependentPropertiesChunks) < iChunkNumberOfInterdependencies.Value()), Panic(EMTPTypeBoundsError)); |
|
216 iInfoInterdependentProperties.iChunkId = aElementId; |
|
217 return iInfoInterdependentProperties; |
|
218 } |
|
219 } |
|
220 |
|
221 TInt CMTPTypeInterdependentPropDesc::ValidateChunkCount() const |
|
222 { |
|
223 TInt ret(KErrNone); |
|
224 if (NumberOfInterdependencies() != (ChunkCount() - 1)) |
|
225 { |
|
226 ret = KMTPDataTypeInvalid; |
|
227 } |
|
228 return ret; |
|
229 } |
|
230 |
|
231 CMTPTypeInterdependentPropDesc::CMTPTypeInterdependentPropDesc() : |
|
232 CMTPTypeCompoundBase(KJustInTimeConstruction, KVariableChunkCount) |
|
233 { |
|
234 const CMTPTypeCompoundBase::TElementInfo KDefaultInfo = {0, EMTPTypeUndefined, {EMTPTypeUndefined, KMTPNotApplicable, KMTPNotApplicable}}; |
|
235 iInfoNumberOfInterdependencies = KDefaultInfo; |
|
236 iInfoNumberOfInterdependencies.iType = EMTPTypeUINT32; |
|
237 iInfoInterdependentProperties = KDefaultInfo; |
|
238 iInfoInterdependentProperties.iType = EMTPTypeInterdependentPropDescElementDataset; |
|
239 } |
|
240 |
|
241 void CMTPTypeInterdependentPropDesc::ConstructL() |
|
242 { |
|
243 ChunkAppendL(iChunkNumberOfInterdependencies); |
|
244 } |
|
245 |
|
246 void CMTPTypeInterdependentPropDesc::AppendElementChunkL(CMTPTypeInterdependentProperties* aElement) |
|
247 { |
|
248 iChunksInterdependentProperties.AppendL(aElement); |
|
249 ChunkAppendL(*aElement); |
|
250 } |
|
251 |
|
252 TInt CMTPTypeInterdependentPropDesc::UpdateWriteSequenceErr(TInt aErr) |
|
253 { |
|
254 iWriteSequenceErr = aErr; |
|
255 return iWriteSequenceErr; |
|
256 } |
|
257 |
|
258 /** |
|
259 MTP InterdependentPropDesc array element dataset factory method. This method is |
|
260 used to create an empty MTP InterdependentPropDesc array element dataset. |
|
261 @return A pointer to the MTP InterdependentPropDesc array element dataset type. |
|
262 Ownership IS transfered. |
|
263 @leave One of the system wide error codes, if unsuccessful. |
|
264 */ |
|
265 EXPORT_C CMTPTypeInterdependentProperties* CMTPTypeInterdependentProperties::NewL() |
|
266 { |
|
267 CMTPTypeInterdependentProperties* self = CMTPTypeInterdependentProperties::NewLC(); |
|
268 CleanupStack::Pop(self); |
|
269 return self; |
|
270 } |
|
271 |
|
272 /** |
|
273 MTP InterdependentPropDesc array element dataset factory method. This method is |
|
274 used to create an empty MTP InterdependentPropDesc array element dataset. A |
|
275 pointer to the data type is placed on the cleanup stack. |
|
276 @return A pointer to the MTP InterdependentPropDesc array element dataset type. |
|
277 Ownership IS transfered. |
|
278 @leave One of the system wide error codes, if unsuccessful. |
|
279 */ |
|
280 EXPORT_C CMTPTypeInterdependentProperties* CMTPTypeInterdependentProperties::NewLC() |
|
281 { |
|
282 CMTPTypeInterdependentProperties* self = new(ELeave) CMTPTypeInterdependentProperties(); |
|
283 CleanupStack::PushL(self); |
|
284 self->ConstructL(); |
|
285 return self; |
|
286 } |
|
287 |
|
288 /** |
|
289 Destructor. |
|
290 */ |
|
291 EXPORT_C CMTPTypeInterdependentProperties::~CMTPTypeInterdependentProperties() |
|
292 { |
|
293 iChunksObjectPropDesc.ResetAndDestroy(); |
|
294 } |
|
295 |
|
296 /** |
|
297 Appends the specified ObjectPropDesc dataset to the InterdependentPropDesc |
|
298 array element array. Ownership of the specified ObjectPropDesc dataset is |
|
299 passed to the InterdependentPropDesc array element array. |
|
300 @param aElement The ObjectPropDesc dataset to append. Ownership IS transferred. |
|
301 @leave One of the system wide error codes, if unsuccessful. |
|
302 */ |
|
303 EXPORT_C void CMTPTypeInterdependentProperties::AppendL(CMTPTypeObjectPropDesc* aElement) |
|
304 { |
|
305 // Increment NumberOfElements. |
|
306 const TUint index(iChunkNumberOfPropDescs.Value()); |
|
307 iChunkNumberOfPropDescs.Set(index + 1); |
|
308 |
|
309 // Append the element. |
|
310 AppendElementChunkL(aElement); |
|
311 } |
|
312 |
|
313 /** |
|
314 Provides the NumberOfPropDescs element value. |
|
315 */ |
|
316 EXPORT_C TUint32 CMTPTypeInterdependentProperties::NumberOfPropDescs() const |
|
317 { |
|
318 return iChunkNumberOfPropDescs.Value(); |
|
319 } |
|
320 |
|
321 /** |
|
322 Provides a non-const reference to the InterdependentPropDesc value quadruple element at |
|
323 the specified index. |
|
324 @param aIndex The index of the required element. |
|
325 @param aValue On successful completion, a non-const reference to the requested |
|
326 element. |
|
327 @leave One of the system wide error codes, if unsuccessful. |
|
328 */ |
|
329 EXPORT_C CMTPTypeObjectPropDesc& CMTPTypeInterdependentProperties::ObjectPropDesc(TUint aIndex) const |
|
330 { |
|
331 return *iChunksObjectPropDesc[aIndex]; |
|
332 } |
|
333 |
|
334 EXPORT_C TInt CMTPTypeInterdependentProperties::FirstWriteChunk(TPtr8& aChunk) |
|
335 { |
|
336 /* |
|
337 Reset the type in preparation for the data stream, by deleting all |
|
338 except the first chunk. |
|
339 */ |
|
340 for (TUint i(ChunkCount() - 1); (i >= (KNumberOfPropDescsChunk + 1)); i--) |
|
341 { |
|
342 ChunkRemove(i); |
|
343 } |
|
344 iChunksObjectPropDesc.ResetAndDestroy(); |
|
345 |
|
346 // Setup the write chunk pointer. |
|
347 TInt err(UpdateWriteSequenceErr(CMTPTypeCompoundBase::FirstWriteChunk(aChunk))); |
|
348 switch (err) |
|
349 { |
|
350 case KMTPChunkSequenceCompletion: |
|
351 err = KErrNone; |
|
352 // Don't break, fall through to set the write sequence state. |
|
353 |
|
354 case KErrNone: |
|
355 // Set the write sequence state. |
|
356 iWriteSequenceState = EInProgress; |
|
357 break; |
|
358 |
|
359 default: |
|
360 break; |
|
361 } |
|
362 |
|
363 return err; |
|
364 } |
|
365 |
|
366 EXPORT_C TInt CMTPTypeInterdependentProperties::NextWriteChunk(TPtr8& aChunk) |
|
367 { |
|
368 TInt err(KMTPChunkSequenceCompletion); |
|
369 |
|
370 if (iWriteSequenceState != EIdle) |
|
371 { |
|
372 err = UpdateWriteSequenceErr(CMTPTypeCompoundBase::NextWriteChunk(aChunk)); |
|
373 if ((iWriteSequenceErr == KMTPChunkSequenceCompletion) && (iWriteSequenceState != EIdle)) |
|
374 { |
|
375 err = KErrNone; |
|
376 } |
|
377 } |
|
378 return err; |
|
379 } |
|
380 |
|
381 EXPORT_C TUint CMTPTypeInterdependentProperties::Type() const |
|
382 { |
|
383 return EMTPTypeInterdependentPropDescElementDataset; |
|
384 } |
|
385 |
|
386 EXPORT_C TBool CMTPTypeInterdependentProperties::CommitRequired() const |
|
387 { |
|
388 return ETrue; |
|
389 } |
|
390 |
|
391 EXPORT_C MMTPType* CMTPTypeInterdependentProperties::CommitChunkL(TPtr8& aChunk) |
|
392 { |
|
393 if (iWriteSequenceErr == KMTPChunkSequenceCompletion) |
|
394 { |
|
395 switch (iWriteSequenceState) |
|
396 { |
|
397 case EInProgress: |
|
398 if ( ( iChunkNumberOfPropDescs.Value() ) && |
|
399 (iChunksObjectPropDesc.Count() < iChunkNumberOfPropDescs.Value())) |
|
400 { |
|
401 // Allocate the next element chunk. |
|
402 CMTPTypeObjectPropDesc* element = CMTPTypeObjectPropDesc::NewLC(); |
|
403 AppendElementChunkL(element); |
|
404 CleanupStack::Pop(element); |
|
405 } |
|
406 else |
|
407 { |
|
408 iWriteSequenceState = EIdle; |
|
409 } |
|
410 break; |
|
411 |
|
412 case EIdle: |
|
413 // Completing the last element in the write sequence. |
|
414 break; |
|
415 |
|
416 default: |
|
417 Panic(EMTPTypeBadStorage); |
|
418 break; |
|
419 } |
|
420 } |
|
421 |
|
422 if (CMTPTypeCompoundBase::CommitRequired()) |
|
423 { |
|
424 CMTPTypeCompoundBase::CommitChunkL(aChunk); |
|
425 } |
|
426 return NULL; |
|
427 } |
|
428 |
|
429 const CMTPTypeCompoundBase::TElementInfo& CMTPTypeInterdependentProperties::ElementInfo(TInt aElementId) const |
|
430 { |
|
431 if (aElementId == KNumberOfPropDescsChunk) |
|
432 { |
|
433 return iInfoNumberOfPropDescs; |
|
434 } |
|
435 else |
|
436 { |
|
437 __ASSERT_ALWAYS(((aElementId - KObjectPropDescChunks) < iChunkNumberOfPropDescs.Value()), Panic(EMTPTypeBoundsError)); |
|
438 iInfoObjectPropDesc.iChunkId = aElementId; |
|
439 return iInfoObjectPropDesc; |
|
440 } |
|
441 } |
|
442 |
|
443 TInt CMTPTypeInterdependentProperties::ValidateChunkCount() const |
|
444 { |
|
445 TInt ret(KErrNone); |
|
446 if (NumberOfPropDescs() != (ChunkCount() - 1)) |
|
447 { |
|
448 ret = KMTPDataTypeInvalid; |
|
449 } |
|
450 return ret; |
|
451 } |
|
452 |
|
453 CMTPTypeInterdependentProperties::CMTPTypeInterdependentProperties() : |
|
454 CMTPTypeCompoundBase(KJustInTimeConstruction, KVariableChunkCount) |
|
455 { |
|
456 const CMTPTypeCompoundBase::TElementInfo KDefaultInfo = {0, EMTPTypeUndefined, {EMTPTypeUndefined, KMTPNotApplicable, KMTPNotApplicable}}; |
|
457 iInfoNumberOfPropDescs = KDefaultInfo; |
|
458 iInfoNumberOfPropDescs.iType = EMTPTypeUINT32; |
|
459 iInfoObjectPropDesc = KDefaultInfo; |
|
460 iInfoObjectPropDesc.iType = EMTPTypeInterdependentPropDescElementDataset; |
|
461 } |
|
462 |
|
463 void CMTPTypeInterdependentProperties::ConstructL() |
|
464 { |
|
465 ChunkAppendL(iChunkNumberOfPropDescs); |
|
466 } |
|
467 |
|
468 void CMTPTypeInterdependentProperties::AppendElementChunkL(CMTPTypeObjectPropDesc* aElement) |
|
469 { |
|
470 iChunksObjectPropDesc.AppendL(aElement); |
|
471 ChunkAppendL(*aElement); |
|
472 } |
|
473 |
|
474 TInt CMTPTypeInterdependentProperties::UpdateWriteSequenceErr(TInt aErr) |
|
475 { |
|
476 iWriteSequenceErr = aErr; |
|
477 return iWriteSequenceErr; |
|
478 } |