mtpfws/mtpfw/datatypes/src/cmtptypeserviceproplist.cpp
changeset 0 d0791faffa3f
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     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/cmtptypeserviceproplist.h>
       
    23 #include <mtp/mtpdatatypeconstants.h>
       
    24 #include <mtp/mtpprotocolconstants.h>
       
    25 
       
    26 #include "mtpdatatypespanic.h"
       
    27 
       
    28 // Dataset constants
       
    29 const TUint CMTPTypeServicePropListElement::KFlatChunkSize(8);
       
    30     
       
    31 const TUint CMTPTypeServicePropList::KNumberOfElementsChunk(0);
       
    32 const TUint CMTPTypeServicePropList::KElementChunks(1);
       
    33 
       
    34 // Dataset element metadata    
       
    35 const CMTPTypeCompoundBase::TElementInfo CMTPTypeServicePropListElement::iElementMetaData[CMTPTypeServicePropListElement::ENumElements] = 
       
    36     {
       
    37         {EIdFlatChunk,  EMTPTypeFlat,       {EMTPTypeUINT32,    0,                  KMTPTypeUINT32Size}},   // EObjectHandle
       
    38         {EIdFlatChunk,  EMTPTypeFlat,       {EMTPTypeUINT16,    4,                  KMTPTypeUINT16Size}},   // EPropertyCode
       
    39         {EIdFlatChunk,  EMTPTypeFlat,       {EMTPTypeUINT16,    6,                  KMTPTypeUINT16Size}},   // EDatatype
       
    40         {EIdValueChunk, EMTPTypeReference,  {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}},    // EValue
       
    41     };
       
    42 
       
    43 /**
       
    44 MTP ObjectPropList dataset factory method. This method is used to create an 
       
    45 empty MTP ObjectPropList dataset. 
       
    46 @return A pointer to the MTP ObjectPropList dataset type. Ownership IS 
       
    47 transfered.
       
    48 @leave One of the system wide error codes, if unsuccessful.
       
    49 */ 
       
    50 EXPORT_C CMTPTypeServicePropList* CMTPTypeServicePropList::NewL()
       
    51     {
       
    52     CMTPTypeServicePropList* self = CMTPTypeServicePropList::NewLC(); 
       
    53     CleanupStack::Pop(self);
       
    54     return self;  
       
    55     }
       
    56 
       
    57 /**
       
    58 MTP ObjectPropList dataset factory method. This method is used to create an 
       
    59 empty MTP ObjectPropList dataset. A pointer to the data type is placed on the
       
    60 cleanup stack.
       
    61 @return A pointer to the MTP ObjectPropList dataset type. Ownership IS 
       
    62 transfered.
       
    63 @leave One of the system wide error codes, if unsuccessful.
       
    64 */ 
       
    65 EXPORT_C CMTPTypeServicePropList* CMTPTypeServicePropList::NewLC()
       
    66     {
       
    67     CMTPTypeServicePropList* self = new(ELeave) CMTPTypeServicePropList();
       
    68     CleanupStack::PushL(self);
       
    69     self->ConstructL();
       
    70     return self;
       
    71     }
       
    72 
       
    73 /**
       
    74 Destructor.
       
    75 */
       
    76 EXPORT_C CMTPTypeServicePropList::~CMTPTypeServicePropList()
       
    77     {
       
    78     iChunksElement.ResetAndDestroy();
       
    79     }
       
    80 
       
    81 /**
       
    82 Appends the specified ObjectPropList value quadruple to the ObjectPropList. 
       
    83 Ownership of the specified ObjectPropList value quadruple is passed to the 
       
    84 ObjectPropList.
       
    85 @param aElement The ObjectPropList value quadruple to append. Ownership IS
       
    86 transferred.
       
    87 @leave KMTPDataTypeInvalid, If an MTP data object is attached to the 
       
    88 ObjectPropList dataset.
       
    89 @leave One of the system wide error codes, if unsuccessful.
       
    90 */
       
    91 EXPORT_C void CMTPTypeServicePropList::AppendL(CMTPTypeServicePropListElement* aElement)
       
    92     {
       
    93     if (iChunkDataObject)
       
    94         {
       
    95         User::Leave(KMTPDataTypeInvalid);
       
    96         }
       
    97         
       
    98     // Increment NumberOfElements.
       
    99     const TUint index(iChunkNumberOfElements.Value());
       
   100     iChunkNumberOfElements.Set(index + 1);
       
   101     
       
   102     // Append the element.
       
   103     AppendElementChunkL(aElement);
       
   104     }
       
   105 
       
   106 /**
       
   107 Appends the specified MTP data object to the ObjectPropList dataset.
       
   108 @leave KMTPDataTypeInvalid, If an MTP data object is already attached to the 
       
   109 ObjectPropList dataset.
       
   110 @leave One of the system wide error codes, if unsuccessful.
       
   111 */
       
   112 EXPORT_C void CMTPTypeServicePropList::AppendDataObjectL(MMTPType& aDataObject)
       
   113     {
       
   114     if (iChunkDataObject)
       
   115         {
       
   116         User::Leave(KMTPDataTypeInvalid);
       
   117         }
       
   118     else
       
   119         {
       
   120         iChunkDataObject = &aDataObject;
       
   121         ChunkAppendL(*iChunkDataObject);
       
   122         }
       
   123     }
       
   124     
       
   125 /**
       
   126 Provides the NumberOfElements element value.
       
   127 */
       
   128 EXPORT_C TUint32 CMTPTypeServicePropList::NumberOfElements() const
       
   129     {
       
   130     return iChunkNumberOfElements.Value();
       
   131     }
       
   132 
       
   133 /**
       
   134 Provides a non-const reference to the ObjectPropList value quadruple element at
       
   135 the specified index.
       
   136 @param aIndex The index of the required element.
       
   137 @return A non-const reference to the requested element.
       
   138 @leave One of the system wide error codes, if unsuccessful.
       
   139 */
       
   140 EXPORT_C CMTPTypeServicePropListElement& CMTPTypeServicePropList::Element(TUint aIndex) const
       
   141     {
       
   142     return *iChunksElement[aIndex];
       
   143     }
       
   144 
       
   145 /**
       
   146 Provides a non-const reference to the optional MTP data object attached to the
       
   147 ObjectPropList dataset.
       
   148 @leave KErrNotFound, If there is no MTP data object attched to the 
       
   149 ObjectPropList dataset.
       
   150 @leave One of the system wide error codes, if unsuccessful.
       
   151 */  
       
   152 EXPORT_C MMTPType& CMTPTypeServicePropList::DataObjectL() const
       
   153     {
       
   154     return *iChunkDataObject;
       
   155     }
       
   156 
       
   157 EXPORT_C TInt CMTPTypeServicePropList::FirstWriteChunk(TPtr8& aChunk)
       
   158     {  
       
   159     /* 
       
   160     Reset the type in preparation for the data stream, by deleting all
       
   161     except the first chunk.
       
   162     */
       
   163     for (TUint i(ChunkCount() - 1); (i >= (KNumberOfElementsChunk + 1)); i--)
       
   164         {
       
   165         ChunkRemove(i);
       
   166         }
       
   167     iChunksElement.ResetAndDestroy();
       
   168     
       
   169     // Setup the write chunk pointer.
       
   170     TInt err(UpdateWriteSequenceErr(CMTPTypeCompoundBase::FirstWriteChunk(aChunk)));
       
   171     switch (err)
       
   172         {
       
   173     case KMTPChunkSequenceCompletion:
       
   174         err = KErrNone;
       
   175         // Don't break, fall through to set the write sequence state.
       
   176         
       
   177     case KErrNone:
       
   178         // Set the write sequence state.
       
   179         iWriteSequenceState = EElementChunks;
       
   180         break;
       
   181         
       
   182     default:
       
   183         break;
       
   184         }
       
   185         
       
   186     return  err;
       
   187     }
       
   188     
       
   189 EXPORT_C TInt CMTPTypeServicePropList::NextWriteChunk(TPtr8& aChunk)
       
   190     {
       
   191     TInt err(KMTPChunkSequenceCompletion);
       
   192     if (iWriteSequenceState != EIdle)
       
   193         {
       
   194         err = UpdateWriteSequenceErr(CMTPTypeCompoundBase::NextWriteChunk(aChunk));
       
   195         if ((iWriteSequenceErr == KMTPChunkSequenceCompletion) && (iWriteSequenceState != EIdle))
       
   196             {
       
   197             err = KErrNone;
       
   198             }   
       
   199         }    
       
   200     return err;
       
   201     }
       
   202 
       
   203 EXPORT_C TUint CMTPTypeServicePropList::Type() const
       
   204     {
       
   205     return EMTPTypeObjectPropListDataset;
       
   206     }
       
   207 
       
   208 EXPORT_C TBool CMTPTypeServicePropList::CommitRequired() const
       
   209     {
       
   210     return ETrue;
       
   211     }
       
   212 
       
   213 EXPORT_C MMTPType* CMTPTypeServicePropList::CommitChunkL(TPtr8& aChunk)
       
   214     {
       
   215     if (iWriteSequenceErr == KMTPChunkSequenceCompletion)
       
   216         {
       
   217         switch (iWriteSequenceState)
       
   218             {
       
   219         case EElementChunks:
       
   220             if ((iChunkNumberOfElements.Value()) && 
       
   221                 (iChunksElement.Count() < iChunkNumberOfElements.Value()))
       
   222                 {
       
   223                 // Allocate the next element chunk.
       
   224                 CMTPTypeServicePropListElement* element = CMTPTypeServicePropListElement::NewLC();
       
   225                 AppendElementChunkL(element);
       
   226                 CleanupStack::Pop(element); 
       
   227                 }
       
   228             else if (iChunkDataObject)
       
   229                 {
       
   230                 iWriteSequenceState = EDataObjectChunk;
       
   231                 ChunkAppendL(*iChunkDataObject);
       
   232                 }
       
   233             else
       
   234                 {
       
   235                 iWriteSequenceState = EIdle;
       
   236                 }
       
   237             break;
       
   238             
       
   239         case EDataObjectChunk:
       
   240         case EIdle:
       
   241             // Completing the last chunk in the write sequence.
       
   242             break;
       
   243             
       
   244         default:
       
   245             Panic(EMTPTypeBadStorage);
       
   246             break;
       
   247             }
       
   248         }
       
   249         
       
   250     if (CMTPTypeCompoundBase::CommitRequired())
       
   251         {
       
   252         CMTPTypeCompoundBase::CommitChunkL(aChunk);
       
   253         }
       
   254 	return NULL;
       
   255     }
       
   256  
       
   257 const CMTPTypeCompoundBase::TElementInfo& CMTPTypeServicePropList::ElementInfo(TInt aElementId) const
       
   258     {
       
   259     if (aElementId == KNumberOfElementsChunk)
       
   260         {
       
   261         return iInfoNumberOfElements;
       
   262         }
       
   263     else
       
   264         {
       
   265         __ASSERT_ALWAYS(((aElementId - KElementChunks) < iChunkNumberOfElements.Value()), Panic(EMTPTypeBoundsError));
       
   266         iInfoElement.iChunkId = aElementId;
       
   267         return iInfoElement; 
       
   268         }
       
   269     }
       
   270 
       
   271 TInt CMTPTypeServicePropList::ValidateChunkCount() const
       
   272     {
       
   273     TInt ret(KErrNone);
       
   274     TUint expected(iChunkDataObject ? (NumberOfElements() + 1) : NumberOfElements());
       
   275     if (expected != (ChunkCount() - 1))
       
   276         {
       
   277         ret = KMTPDataTypeInvalid;
       
   278         }
       
   279     return ret;
       
   280     }
       
   281 
       
   282 CMTPTypeServicePropList::CMTPTypeServicePropList() :
       
   283     CMTPTypeCompoundBase(KJustInTimeConstruction, KVariableChunkCount)
       
   284     {
       
   285     const CMTPTypeCompoundBase::TElementInfo KDefaultInfo = {0, EMTPTypeUndefined, {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}};
       
   286     iInfoNumberOfElements       = KDefaultInfo; 
       
   287     iInfoNumberOfElements.iType = EMTPTypeUINT32;
       
   288     iInfoElement                = KDefaultInfo; 
       
   289     iInfoElement.iType          = EMTPTypeObjectPropListElementDataset;
       
   290     }
       
   291 
       
   292 void CMTPTypeServicePropList::ConstructL()
       
   293     {
       
   294     ChunkAppendL(iChunkNumberOfElements);
       
   295     }
       
   296     
       
   297 void CMTPTypeServicePropList::AppendElementChunkL(CMTPTypeServicePropListElement* aElement)
       
   298     {
       
   299     iChunksElement.AppendL(aElement);
       
   300     ChunkAppendL(*aElement);
       
   301     }
       
   302     
       
   303 TInt CMTPTypeServicePropList::UpdateWriteSequenceErr(TInt aErr)
       
   304     {
       
   305     iWriteSequenceErr = aErr;
       
   306     return iWriteSequenceErr;        
       
   307     }
       
   308 
       
   309 /**
       
   310 MTP ObjectPropList element dataset factory method. This method is used to 
       
   311 create an MTP ObjectPropList element dataset type with the default 
       
   312 ElementDataType defined for the specified ElementPropertyCode, and the default 
       
   313 ElementObjectHandle and ElementValue values. 
       
   314 @param aPropertyCode The datacode identifying the ObjectPropDesc which 
       
   315 describes the property.
       
   316 @return A pointer to the ObjectPropList element dataset type. 
       
   317 Ownership IS transfered.
       
   318 @leave One of the system wide error codes, if unsuccessful.
       
   319 */ 
       
   320 EXPORT_C CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewL(TUint16 aPropertyCode)
       
   321     {
       
   322     CMTPTypeServicePropListElement* self = NewLC(aPropertyCode);
       
   323     CleanupStack::Pop(self); 
       
   324     return self;
       
   325     }
       
   326 
       
   327 /**
       
   328 MTP ObjectPropList element dataset factory method. This method is used to 
       
   329 create an MTP ObjectPropList element dataset type with with the default 
       
   330 ElementDataType defined for the specified ElementPropertyCode, and the default 
       
   331 ElementObjectHandle and ElementValue values. A pointer to the data type is 
       
   332 placed on the cleanup stack.
       
   333 @param aPropertyCode The datacode identifying the ObjectPropDesc which 
       
   334 describes the property.
       
   335 @return A pointer to the ObjectPropList element dataset type. 
       
   336 Ownership IS transfered.
       
   337 @leave One of the system wide error codes, if unsuccessful.
       
   338 */ 
       
   339 EXPORT_C CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewLC(TUint16 aPropertyCode)
       
   340     {
       
   341     CMTPTypeObjectPropDesc::TPropertyInfo info;
       
   342     CMTPTypeObjectPropDesc::PropertyInfoL(aPropertyCode, info);
       
   343 
       
   344     CMTPTypeServicePropListElement* self = new(ELeave) CMTPTypeServicePropListElement();
       
   345     CleanupStack::PushL(self); 
       
   346     self->ConstructL(aPropertyCode, info.iDataType, NULL, NULL);
       
   347     return self;
       
   348     }
       
   349 
       
   350 /**
       
   351 MTP ObjectPropList element dataset factory method. This method is used to 
       
   352 create an MTP ObjectPropList element dataset type with with the default 
       
   353 ElementDataType defined for the specified ElementPropertyCode, and the 
       
   354 specified ElementObjectHandle and ElementValue values. 
       
   355 @param aObjectHandle The ObjectHandle of the object to which the property 
       
   356 applies.
       
   357 @param aPropertyCode The datacode identifying the ObjectPropDesc which 
       
   358 describes the property.
       
   359 @param aValue The value of the property.
       
   360 @return A pointer to the ObjectPropList element dataset type. 
       
   361 Ownership IS transfered.
       
   362 @leave One of the system wide error codes, if unsuccessful.
       
   363 */ 
       
   364 EXPORT_C CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewL(TUint32 aObjectHandle, TUint16 aPropertyCode, const MMTPType& aValue)
       
   365     {
       
   366     CMTPTypeServicePropListElement* self = NewLC(aObjectHandle, aPropertyCode, aValue);
       
   367     CleanupStack::Pop(self);
       
   368     return self;
       
   369     }
       
   370 
       
   371 /**
       
   372 MTP ObjectPropList element dataset factory method. This method is used to 
       
   373 create an MTP ObjectPropList element dataset type with with the default 
       
   374 ElementDataType defined for the specified ElementPropertyCode, and the 
       
   375 specified ElementObjectHandle and ElementValue values. A pointer to the data 
       
   376 type is placed on the cleanup stack.
       
   377 @param aObjectHandle The ObjectHandle of the object to which the property 
       
   378 applies.
       
   379 @param aPropertyCode The datacode identifying the ObjectPropDesc which 
       
   380 describes the property.
       
   381 @param aValue The value of the property.
       
   382 @return A pointer to the ObjectPropList element dataset type. 
       
   383 Ownership IS transfered.
       
   384 @leave One of the system wide error codes, if unsuccessful.
       
   385 */ 
       
   386 EXPORT_C CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewLC(TUint32 aObjectHandle, TUint16 aPropertyCode, const MMTPType& aValue)
       
   387     {
       
   388     CMTPTypeObjectPropDesc::TPropertyInfo info;
       
   389     CMTPTypeObjectPropDesc::PropertyInfoL(aPropertyCode, info);
       
   390 
       
   391     CMTPTypeServicePropListElement* self = new(ELeave) CMTPTypeServicePropListElement();
       
   392     CleanupStack::PushL(self); 
       
   393     self->ConstructL(aPropertyCode, info.iDataType, &aObjectHandle, &aValue);
       
   394     return self;
       
   395     }
       
   396 
       
   397 /**
       
   398 MTP ObjectPropList element dataset factory method. This method is used to 
       
   399 create an MTP ObjectPropList element dataset type with the specified 
       
   400 ElementPropertyCode and ElementDataType values, and the default 
       
   401 ElementObjectHandle and ElementValue values. 
       
   402 @param aPropertyCode The datacode identifying the ObjectPropDesc which 
       
   403 describes the property.
       
   404 @param aDataType The datacode identifying the datatype of the property.
       
   405 @return A pointer to the ObjectPropList element dataset type. 
       
   406 Ownership IS transfered.
       
   407 @leave One of the system wide error codes, if unsuccessful.
       
   408 */ 
       
   409 EXPORT_C CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewL(TUint16 aPropertyCode, TUint16 aDataType)
       
   410     {
       
   411     CMTPTypeServicePropListElement* self = NewLC(aPropertyCode, aDataType);
       
   412     CleanupStack::Pop(self);
       
   413     return self;
       
   414     }
       
   415 
       
   416 /**
       
   417 MTP ObjectPropList element dataset factory method. This method is used to 
       
   418 create an MTP ObjectPropList element dataset type with the specified 
       
   419 ElementPropertyCode and ElementDataType values, and the default 
       
   420 ElementObjectHandle and ElementValue values. A pointer to the data type is 
       
   421 placed on the cleanup stack.
       
   422 @param aPropertyCode The datacode identifying the ObjectPropDesc which 
       
   423 describes the property.
       
   424 @param aDataType The datacode identifying the datatype of the property.
       
   425 @return A pointer to the ObjectPropList element dataset type. 
       
   426 Ownership IS transfered.
       
   427 @leave One of the system wide error codes, if unsuccessful.
       
   428 */ 
       
   429 EXPORT_C CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewLC(TUint16 aPropertyCode, TUint16 aDataType)
       
   430     {
       
   431     CMTPTypeServicePropListElement* self = new(ELeave) CMTPTypeServicePropListElement();
       
   432     CleanupStack::PushL(self); 
       
   433     self->ConstructL(aPropertyCode, aDataType, NULL, NULL);
       
   434     return self;
       
   435     }
       
   436 
       
   437 /**
       
   438 MTP ObjectPropList element dataset factory method. This method is used to 
       
   439 create an MTP ObjectPropList element dataset type with the specified values. 
       
   440 @param aObjectHandle The ObjectHandle of the object to which the property 
       
   441 applies.
       
   442 @param aPropertyCode The datacode identifying the ObjectPropDesc which 
       
   443 describes the property.
       
   444 @param aDataType The datacode identifying the datatype of the property.
       
   445 @param aValue The value of the property.
       
   446 @return A pointer to the ObjectPropList element dataset type. 
       
   447 Ownership IS transfered.
       
   448 @leave One of the system wide error codes, if unsuccessful.
       
   449 */ 
       
   450 EXPORT_C CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewL(TUint32 aObjectHandle, TUint16 aPropertyCode, TUint16 aDataType, const MMTPType& aValue)
       
   451     {
       
   452     CMTPTypeServicePropListElement* self = NewLC(aObjectHandle, aPropertyCode, aDataType, aValue);
       
   453     CleanupStack::Pop(self);
       
   454     return self;    
       
   455     }
       
   456 
       
   457 /**
       
   458 MTP ObjectPropList element dataset factory method. This method is used to 
       
   459 create an MTP ObjectPropList element dataset type with the specified values. A 
       
   460 pointer to the data type is placed on the cleanup stack.
       
   461 @param aObjectHandle The ObjectHandle of the object to which the property 
       
   462 applies.
       
   463 @param aPropertyCode The datacode identifying the ObjectPropDesc which 
       
   464 describes the property.
       
   465 @param aDataType The datacode identifying the datatype of the property.
       
   466 @param aValue The value of the property.
       
   467 @return A pointer to the ObjectPropList element dataset type. 
       
   468 Ownership IS transfered.
       
   469 @leave One of the system wide error codes, if unsuccessful.
       
   470 */ 
       
   471 EXPORT_C CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewLC(TUint32 aObjectHandle, TUint16 aPropertyCode, TUint16 aDataType, const MMTPType& aValue)
       
   472     {
       
   473     CMTPTypeServicePropListElement* self = new(ELeave) CMTPTypeServicePropListElement();
       
   474     CleanupStack::PushL(self); 
       
   475     self->ConstructL(aPropertyCode, aDataType, &aObjectHandle, &aValue);
       
   476     return self;    
       
   477     }
       
   478 
       
   479 /**
       
   480 Destructor.
       
   481 */
       
   482 EXPORT_C CMTPTypeServicePropListElement::~CMTPTypeServicePropListElement()
       
   483     {
       
   484     iChunkFlat.Close();
       
   485     iChunkValue.Close();
       
   486     }
       
   487 
       
   488 EXPORT_C TInt CMTPTypeServicePropListElement::FirstWriteChunk(TPtr8& aChunk)
       
   489     {
       
   490     // Setup the write chunk pointer.
       
   491     TInt err(CMTPTypeCompoundBase::FirstWriteChunk(aChunk));
       
   492     switch (err)
       
   493         {
       
   494     case KMTPChunkSequenceCompletion:
       
   495         err = KErrNone;
       
   496         // Don't break, fall through to set the write sequence state.
       
   497         
       
   498     case KErrNone:
       
   499         // Set the write sequence state.
       
   500         iWriteSequenceState = EFlatChunk;
       
   501         break;
       
   502         
       
   503     default:
       
   504         break;
       
   505         }        
       
   506     return  err;
       
   507     }
       
   508 
       
   509 EXPORT_C TUint CMTPTypeServicePropListElement::Type() const
       
   510     {
       
   511     return EMTPTypeObjectPropListElementDataset;
       
   512     }
       
   513 
       
   514 EXPORT_C TBool CMTPTypeServicePropListElement::CommitRequired() const
       
   515     {
       
   516     return ETrue;
       
   517     }
       
   518 
       
   519 EXPORT_C MMTPType* CMTPTypeServicePropListElement::CommitChunkL(TPtr8& aChunk)
       
   520     {
       
   521     switch (iWriteSequenceState)
       
   522         {
       
   523     case EFlatChunk:
       
   524         /* 
       
   525         ElementDatatype is available, (re)construct storage for the 
       
   526         ElementValue.
       
   527         */
       
   528         iChunkValue.Close();
       
   529         iChunkValue.OpenL(Uint16L(EDatatype));
       
   530         
       
   531         // Update the write sequence state.
       
   532         iWriteSequenceState = EValueChunk;
       
   533         break;
       
   534         
       
   535     case EValueChunk:
       
   536         // Update the write sequence state.
       
   537         iWriteSequenceState = EIdle;
       
   538         break;
       
   539         
       
   540     default:
       
   541         break;
       
   542         }
       
   543         
       
   544     if (CMTPTypeCompoundBase::CommitRequired())
       
   545         {
       
   546         CMTPTypeCompoundBase::CommitChunkL(aChunk);
       
   547         }
       
   548 	return NULL;
       
   549     }
       
   550     
       
   551 const CMTPTypeCompoundBase::TElementInfo& CMTPTypeServicePropListElement::ElementInfo(TInt aElementId) const
       
   552     {
       
   553     return iElementInfo[aElementId];
       
   554     }
       
   555 
       
   556 TBool CMTPTypeServicePropListElement::WriteableElementL(TInt aElementId) const
       
   557     {
       
   558     TBool ret(EFalse);
       
   559 
       
   560     if (!iInitialised)
       
   561         {
       
   562         ret = ETrue;    
       
   563         }
       
   564     else
       
   565         {
       
   566         switch (aElementId)
       
   567             {
       
   568         case EObjectHandle:
       
   569         case EValue:
       
   570             ret = ETrue;
       
   571             break;
       
   572 
       
   573         default:
       
   574             break;
       
   575             }   
       
   576         }
       
   577         
       
   578     return ret;
       
   579     }
       
   580 
       
   581 /*
       
   582 MTP ObjectPropList element dataset "pre-production" factory method for datasets
       
   583 which will be populated from an MTP write data stream. This method is used to 
       
   584 create a partially constructed MTP ObjectPropList element dataset type prior to
       
   585 the construction characteristics being known. Construction of the element 
       
   586 dataset is completed on-the-fly as it is written to from an MTP write data 
       
   587 stream. A pointer to the data type is placed on the cleanup stack.
       
   588 @return A pointer to the ObjectPropList element dataset type. 
       
   589 Ownership IS transfered.
       
   590 @leave One of the system wide error codes, if unsuccessful.
       
   591 */
       
   592 CMTPTypeServicePropListElement* CMTPTypeServicePropListElement::NewLC()
       
   593     {
       
   594     CMTPTypeServicePropListElement* self = new(ELeave) CMTPTypeServicePropListElement();
       
   595     CleanupStack::PushL(self);
       
   596     self->ConstructL();
       
   597     return self;
       
   598     }
       
   599 
       
   600 CMTPTypeServicePropListElement::CMTPTypeServicePropListElement() :
       
   601     CMTPTypeCompoundBase(KJustInTimeConstruction, EIdNumChunks),
       
   602     iElementInfo(iElementMetaData, ENumElements),
       
   603     iChunkFlat(KFlatChunkSize, *this)
       
   604     {
       
   605 
       
   606     }
       
   607 
       
   608 void CMTPTypeServicePropListElement::ConstructL()
       
   609     {
       
   610     for (TUint i(0); (i < ENumElements); i++)
       
   611         {
       
   612         const TElementInfo& element(iElementInfo[i]);
       
   613         if (ChunkCount() <= element.iChunkId)
       
   614             {
       
   615             MMTPType* chunk(NULL);
       
   616             
       
   617             switch (element.iChunkId)
       
   618                 {
       
   619             case EIdFlatChunk:
       
   620                 iChunkFlat.OpenL();
       
   621                 chunk = &iChunkFlat;
       
   622                 break;
       
   623                 
       
   624             case EIdValueChunk:
       
   625                 /* 
       
   626                 iChunkValue is always opened elsewhere. CommitChunkL in the  
       
   627                 just-in-time construction case, or other ConstructL overloads in
       
   628                 normal construction cases.
       
   629                 */
       
   630                 chunk = &iChunkValue;
       
   631                 break;
       
   632                 
       
   633             default:
       
   634                 Panic(EMTPTypeBoundsError);
       
   635                 break;
       
   636                 }
       
   637                 
       
   638             if (chunk)
       
   639                 {
       
   640                 ChunkAppendL(*chunk);
       
   641                 }
       
   642             }
       
   643         }
       
   644     }
       
   645 
       
   646 void CMTPTypeServicePropListElement::ConstructL(TUint16 aPropertyCode, TUint16 aDataType, const TUint32* aObjectHandle, const MMTPType* aValue)
       
   647     {
       
   648     iChunkValue.OpenL(aDataType);
       
   649     ConstructL();
       
   650 
       
   651     // Set mandatory construction values.
       
   652     SetUint16L(EPropertyCode, aPropertyCode);
       
   653     SetUint16L(EDatatype, aDataType);
       
   654 
       
   655     // Set optional construction values.
       
   656     if (aObjectHandle)
       
   657         {
       
   658         SetUint32L(EObjectHandle, *aObjectHandle);
       
   659         }
       
   660 
       
   661     if (aValue)
       
   662         {
       
   663         SetL(EValue, *aValue);
       
   664         }
       
   665     
       
   666     iInitialised = ETrue;
       
   667     }
       
   668