mtpfws/mtpfw/datatypes/src/cmtptypedevicepropdesc.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  @internalComponent
       
    19 */
       
    20 
       
    21 #include <mtp/cmtptypedevicepropdesc.h>
       
    22 #include <mtp/mtpdatatypeconstants.h>
       
    23 #include <mtp/mtpprotocolconstants.h>
       
    24 
       
    25 #include "mtpdatatypespanic.h"
       
    26 
       
    27 // Dataset constants
       
    28 const TUint CMTPTypeDevicePropDesc::KFlat1ChunkSize(5);
       
    29 const TUint CMTPTypeDevicePropDesc::KNumChunksWithoutForm(EIdFormFlagChunk + 1);
       
    30 const TUint CMTPTypeDevicePropDesc::KNumChunksWithForm(EIdFormChunk + 1);
       
    31 
       
    32 const TUint CMTPTypeDevicePropDescEnumerationForm::KNumberOfValuesChunk(0);
       
    33 const TUint CMTPTypeDevicePropDescEnumerationForm::KValueChunks(1);
       
    34 
       
    35 // Dataset element metadata    
       
    36 const CMTPTypeCompoundBase::TElementInfo CMTPTypeDevicePropDesc::iElementMetaData[CMTPTypeDevicePropDesc::ENumElements] = 
       
    37     {
       
    38         {EIdFlat1Chunk,         EMTPTypeFlat,       {EMTPTypeUINT16,    0,                  KMTPTypeUINT16Size}},   // EDevicePropertyCode
       
    39         {EIdFlat1Chunk,         EMTPTypeFlat,       {EMTPTypeUINT16,    2,                  KMTPTypeUINT16Size}},   // EDatatype
       
    40         {EIdFlat1Chunk,         EMTPTypeFlat,       {EMTPTypeUINT8,     4,                  KMTPTypeUINT8Size}},    // EGetSet
       
    41         {EIdDefaultValueChunk,  EMTPTypeReference,  {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}},    // EFactoryDefaultValue
       
    42         {EIdCurrentValueChunk,  EMTPTypeReference,  {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}},    // ECurrentValue
       
    43         {EIdFormFlagChunk,      EMTPTypeUINT8,      {EMTPTypeUINT8,     KMTPNotApplicable,  KMTPNotApplicable}},    // EFormFlag
       
    44         {EIdFormChunk,          EMTPTypeReference,  {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}},    // EForm
       
    45     };
       
    46 
       
    47 /**
       
    48 MTP DevicePropDesc dataset factory method. This method is used to create an 
       
    49 empty MTP DevicePropDesc dataset type with the default Datatype and Form Flag 
       
    50 defined for the specified PropertyCode. 
       
    51 @param aPropertyCode The ObjectPropertyCode of the property being described by 
       
    52 the DevicePropDesc dataset.
       
    53 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
    54 transfered.
       
    55 @leave One of the system wide error codes, if unsuccessful.
       
    56 */ 
       
    57 EXPORT_C CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewL(TUint16 aPropertyCode)
       
    58     {
       
    59     CMTPTypeDevicePropDesc* self = NewLC(aPropertyCode);
       
    60     CleanupStack::Pop(self);
       
    61     return self;    
       
    62     }
       
    63 
       
    64 /**
       
    65 MTP DevicePropDesc dataset factory method. This method is used to create an 
       
    66 empty MTP DevicePropDesc dataset type with the default Datatype and Form Flag 
       
    67 defined for the specified PropertyCode. A pointer to the data type is placed on
       
    68 the cleanup stack.
       
    69 @param aPropertyCode The ObjectPropertyCode of the property being described by 
       
    70 the DevicePropDesc dataset.
       
    71 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
    72 transfered.
       
    73 @leave One of the system wide error codes, if unsuccessful.
       
    74 */ 
       
    75 EXPORT_C CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewLC(TUint16 aPropertyCode)
       
    76     {    
       
    77     CMTPTypeDevicePropDesc* self = new (ELeave) CMTPTypeDevicePropDesc(); 
       
    78     CleanupStack::PushL(self); 
       
    79     self->ConstructL(aPropertyCode, NULL);
       
    80     return self;    
       
    81     }
       
    82 
       
    83 /**
       
    84 MTP DevicePropDesc dataset factory method. This method is used to create an 
       
    85 MTP DevicePropDesc dataset type with the default Datatype and Form Flag 
       
    86 defined for the specified PropertyCode, and the specified FORM. 
       
    87 @param aPropertyCode The ObjectPropertyCode of the property being described by 
       
    88 the DevicePropDesc dataset.
       
    89 @param aForm The optional DevicePropDesc FORM dataset.
       
    90 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
    91 transfered.
       
    92 @leave KErrNotSupported, if a FORM dataset is not defined for the property.
       
    93 @leave One of the system wide error codes, if unsuccessful.
       
    94 */ 
       
    95 EXPORT_C CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewL(TUint16 aPropertyCode, const MMTPType& aForm)
       
    96     {
       
    97     CMTPTypeDevicePropDesc* self = NewLC(aPropertyCode, aForm);
       
    98     CleanupStack::Pop(self); 
       
    99     return self;    
       
   100     }
       
   101 
       
   102 /**
       
   103 MTP DevicePropDesc dataset factory method. This method is used to create an 
       
   104 MTP DevicePropDesc dataset type with the default Datatype and Form Flag 
       
   105 defined for the specified PropertyCode, and the specified FORM. A pointer 
       
   106 to the data type is placed on the cleanup stack.
       
   107 @param aPropertyCode The ObjectPropertyCode of the property being described by 
       
   108 the DevicePropDesc dataset.
       
   109 @param aForm The optional DevicePropDesc FORM dataset.
       
   110 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
   111 transfered.
       
   112 @leave KErrNotSupported, if a FORM dataset is not defined for the property.
       
   113 @leave One of the system wide error codes, if unsuccessful.
       
   114 */ 
       
   115 EXPORT_C CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewLC(TUint16 aPropertyCode, const MMTPType& aForm)
       
   116     {    
       
   117     CMTPTypeDevicePropDesc* self = new (ELeave) CMTPTypeDevicePropDesc(); 
       
   118     CleanupStack::PushL(self); 
       
   119     self->ConstructL(aPropertyCode, &aForm);
       
   120     return self;    
       
   121     }
       
   122 
       
   123 /**
       
   124 MTP DevicePropDesc dataset factory method. This method is used to create an 
       
   125 MTP DevicePropDesc dataset type with the default Datatype defined for the 
       
   126 specified PropertyCode, and the specified Form Flag and FORM.  
       
   127 @param aPropertyCode The ObjectPropertyCode of the property being described by 
       
   128 the DevicePropDesc dataset.
       
   129 @param aGetSet The Get/Set flag of the DevicePropDesc.
       
   130 @param aFormFlag The required Form Flag of the DevicePropDesc.
       
   131 @param aForm The optional DevicePropDesc FORM dataset.
       
   132 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
   133 transfered.
       
   134 @leave KErrNotSupported, if a FORM dataset is not defined for the property.
       
   135 @leave One of the system wide error codes, if unsuccessful.
       
   136 */ 
       
   137 EXPORT_C CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewL(TUint16 aPropertyCode, TUint8 aGetSet, TUint8 aFormFlag, const MMTPType* aForm)
       
   138     {
       
   139     CMTPTypeDevicePropDesc* self = NewLC(aPropertyCode, aGetSet, aFormFlag, aForm);
       
   140     CleanupStack::Pop(self);
       
   141     return self;    
       
   142     }
       
   143 
       
   144 /**
       
   145 MTP DevicePropDesc dataset factory method. This method is used to create an 
       
   146 MTP DevicePropDesc dataset type with the default Datatype defined for the 
       
   147 specified PropertyCode, and the specified Form Flag and FORM. A pointer 
       
   148 to the data type is placed on the cleanup stack.
       
   149 @param aPropertyCode The ObjectPropertyCode of the property being described by 
       
   150 the DevicePropDesc dataset.
       
   151 @param aGetSet The Get/Set flag of the DevicePropDesc.
       
   152 @param aFormFlag The required Form Flag of the DevicePropDesc.
       
   153 @param aForm The optional DevicePropDesc FORM dataset.
       
   154 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
   155 transfered.
       
   156 @leave KErrNotSupported, if a FORM dataset is not defined for the property.
       
   157 @leave One of the system wide error codes, if unsuccessful.
       
   158 */ 
       
   159 EXPORT_C CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewLC(TUint16 aPropertyCode, TUint8 aGetSet, TUint8 aFormFlag, const MMTPType* aForm)
       
   160     {
       
   161     CMTPTypeDevicePropDesc* self = new (ELeave) CMTPTypeDevicePropDesc(); 
       
   162     CleanupStack::PushL(self); 
       
   163     TPropertyInfo info;
       
   164     PropertyInfoL(aPropertyCode, info);
       
   165     info.iGetSet    = aGetSet;
       
   166     info.iFormFlag  = aFormFlag;
       
   167     self->ConstructL(aPropertyCode, info, aForm);
       
   168     return self;    
       
   169     }
       
   170 
       
   171 /**
       
   172 MTP DevicePropDesc dataset factory method. This method is used to create an  
       
   173 MTP DevicePropDesc dataset type with the specified values.
       
   174 @param aPropertyCode The ObjectPropertyCode of the property being described by 
       
   175 the DevicePropDesc dataset.
       
   176 @param aInfo The MTP DevicePropDesc dataset characteristics (meta data).
       
   177 @param aForm The optional DevicePropDesc FORM dataset.
       
   178 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
   179 transfered.
       
   180 @leave KErrNotSupported, if a FORM dataset is not defined for the property.
       
   181 @leave One of the system wide error codes, if unsuccessful.
       
   182 */    
       
   183 EXPORT_C CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewL(TUint16 aPropertyCode, const TPropertyInfo& aInfo, const MMTPType* aForm)
       
   184     {
       
   185     CMTPTypeDevicePropDesc* self = CMTPTypeDevicePropDesc::NewLC(aPropertyCode, aInfo, aForm); 
       
   186     CleanupStack::Pop(self);
       
   187     return self; 
       
   188     }
       
   189 
       
   190 /**
       
   191 MTP DevicePropDesc dataset factory method. This method is used to create an  
       
   192 MTP DevicePropDesc dataset type with the specified values. A pointer to the 
       
   193 data type is placed on the cleanup stack.
       
   194 @param aPropertyCode The ObjectPropertyCode of the property being described by 
       
   195 the DevicePropDesc dataset.
       
   196 @param aInfo The MTP DevicePropDesc dataset characteristics (meta data).
       
   197 @param aForm The optional DevicePropDesc FORM dataset.
       
   198 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
   199 transfered.
       
   200 @leave KErrNotSupported, if a FORM dataset is not defined for the property.
       
   201 @leave One of the system wide error codes, if unsuccessful.
       
   202 */ 
       
   203 EXPORT_C CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewLC(TUint16 aPropertyCode, const TPropertyInfo& aInfo, const MMTPType* aForm)
       
   204     {
       
   205     CMTPTypeDevicePropDesc* self = new (ELeave) CMTPTypeDevicePropDesc(); 
       
   206     CleanupStack::PushL(self); 
       
   207     self->ConstructL(aPropertyCode, aInfo, aForm);
       
   208     return self;    
       
   209     }
       
   210 
       
   211 /**
       
   212 Destructor.
       
   213 */
       
   214 EXPORT_C CMTPTypeDevicePropDesc::~CMTPTypeDevicePropDesc()
       
   215     {
       
   216     iChunkFlat1.Close();
       
   217     iChunkDefaultValue.Close();
       
   218     iChunkCurrentValue.Close();
       
   219     iChunkForm.Close();
       
   220     }
       
   221 
       
   222 EXPORT_C TInt CMTPTypeDevicePropDesc::FirstWriteChunk(TPtr8& aChunk)
       
   223     {  
       
   224     /* 
       
   225     Reset the type in preparation for the data stream, by deleting all
       
   226     except the first chunk.
       
   227     */
       
   228     for (TUint i(ChunkCount() - 1); (i >= (EIdFlat1Chunk + 1)); i--)
       
   229         {
       
   230         ChunkRemove(i);
       
   231         }
       
   232         
       
   233     // Setup the write chunk pointer.
       
   234     TInt err(UpdateWriteSequenceErr(CMTPTypeCompoundBase::FirstWriteChunk(aChunk)));
       
   235     switch (err)
       
   236         {
       
   237     case KMTPChunkSequenceCompletion:
       
   238         err = KErrNone;
       
   239         // Don't break, fall through to set the write sequence state.
       
   240         
       
   241     case KErrNone:
       
   242         // Set the write sequence state.
       
   243         iWriteSequenceState = EWriteFlat1Chunk; 
       
   244         
       
   245         /* 
       
   246         Set the write sequence completion state. Initially assume that the 
       
   247         DevicePropDesc has a FORM field. If no FORM field is subsequently
       
   248         detected in the write data stream then the completion state is 
       
   249         adjusted accordingly.
       
   250         */
       
   251         iWriteSequenceCompletionState = EWriteFormChunk;
       
   252         break;
       
   253         
       
   254     default:
       
   255         break;
       
   256         }
       
   257         
       
   258     return  err;
       
   259     }
       
   260     
       
   261 EXPORT_C TInt CMTPTypeDevicePropDesc::NextWriteChunk(TPtr8& aChunk)
       
   262     {
       
   263     TInt err(KMTPChunkSequenceCompletion);
       
   264     
       
   265     if (iWriteSequenceState != EWriteIdle)
       
   266         {
       
   267         err = UpdateWriteSequenceErr(CMTPTypeCompoundBase::NextWriteChunk(aChunk));
       
   268         if ((iWriteSequenceErr == KMTPChunkSequenceCompletion) && (iWriteSequenceState != EWriteIdle))
       
   269             {
       
   270             err = KErrNone;
       
   271             }   
       
   272         }    
       
   273     return err;
       
   274     }
       
   275  
       
   276 EXPORT_C TUint CMTPTypeDevicePropDesc::Type() const
       
   277     {
       
   278     return EMTPTypeDevicePropDescDataset;
       
   279     }
       
   280     
       
   281 EXPORT_C TBool CMTPTypeDevicePropDesc::CommitRequired() const
       
   282     {
       
   283     return ETrue;
       
   284     }
       
   285 
       
   286 EXPORT_C MMTPType* CMTPTypeDevicePropDesc::CommitChunkL(TPtr8& aChunk)
       
   287     {
       
   288     if (iWriteSequenceErr == KMTPChunkSequenceCompletion)
       
   289         {
       
   290         switch (iWriteSequenceState)
       
   291             {
       
   292         case EWriteFlat1Chunk:     
       
   293             /* 
       
   294             Datatype is available, allocate sufficient chunk storage for 
       
   295             and append the EFactoryDefaultValue and ECurrentValue chunks.
       
   296             */
       
   297             iChunkDefaultValue.Close();
       
   298             iChunkDefaultValue.OpenL(Uint16L(EDatatype));
       
   299             ChunkAppendL(iChunkDefaultValue);
       
   300             break;
       
   301             
       
   302         case EWriteDefaultValueChunk:
       
   303             iChunkCurrentValue.Close();
       
   304             iChunkCurrentValue.OpenL(Uint16L(EDatatype));
       
   305             ChunkAppendL(iChunkCurrentValue);                        
       
   306             break;
       
   307             
       
   308         case EWriteCurrentValueChunk:
       
   309         	ChunkAppendL(iChunkFormFlag);
       
   310         	break;
       
   311             
       
   312         case EWriteFormFlagChunk: 
       
   313             /* 
       
   314             FormFlag and Datatype are available, allocate sufficient storage for 
       
   315             and append the FORM chunk.
       
   316             */
       
   317             {
       
   318             iChunkForm.Close();
       
   319             
       
   320             TUint8 flag(Uint8L(EFormFlag));
       
   321             iChunkForm.SetMeta(flag, Uint16L(EDatatype));
       
   322             
       
   323             if (HasFormField(flag))
       
   324                 {
       
   325                 iChunkForm.OpenL(iElementInfo[EIdFormChunk].iType);
       
   326                 ChunkAppendL(iChunkForm);
       
   327                 SetExpectedChunkCount(KNumChunksWithForm);
       
   328                 }
       
   329             else
       
   330                 {
       
   331                 // Adjust the write sequence completion state.            
       
   332                 iWriteSequenceCompletionState = EWriteFormFlagChunk;
       
   333                 }   
       
   334             }
       
   335             break;
       
   336             
       
   337         case EWriteFormChunk:
       
   338         case EWriteIdle:
       
   339         default:
       
   340             break;
       
   341             }
       
   342     if (iWriteSequenceState < iWriteSequenceCompletionState)
       
   343         {
       
   344         iWriteSequenceState++;
       
   345         }
       
   346     else
       
   347         {
       
   348         iWriteSequenceState = EWriteIdle;
       
   349         }
       
   350     }
       
   351         
       
   352     if (CMTPTypeCompoundBase::CommitRequired())
       
   353         {
       
   354         CMTPTypeCompoundBase::CommitChunkL(aChunk);
       
   355         }
       
   356     return NULL;
       
   357     }
       
   358     
       
   359 void CMTPTypeDevicePropDesc::PropertyInfoL(TUint16 aPropertyCode, TPropertyInfo& aInfo)
       
   360     {    
       
   361     switch (aPropertyCode)
       
   362         {        
       
   363     case EMTPDevicePropCodeUndefined:
       
   364         aInfo.iDataType     = EMTPTypeUndefined;
       
   365         aInfo.iFormFlag     = ENone;
       
   366         aInfo.iGetSet       = EReadOnly;
       
   367         break;
       
   368         
       
   369     case EMTPDevicePropCodeBatteryLevel:
       
   370         aInfo.iDataType     = EMTPTypeUINT8;
       
   371         aInfo.iFormFlag     = ERangeForm;
       
   372         aInfo.iGetSet       = EReadOnly;
       
   373         break;
       
   374         
       
   375     case EMTPDevicePropCodeFunctionalMode:
       
   376         aInfo.iDataType     = EMTPTypeUINT16;
       
   377         aInfo.iFormFlag     = EEnumerationForm;
       
   378         aInfo.iGetSet       = EReadOnly;
       
   379         break;
       
   380         
       
   381     case EMTPDevicePropCodeImageSize:
       
   382         aInfo.iDataType     = EMTPTypeString;
       
   383         aInfo.iFormFlag     = ENone;
       
   384         aInfo.iGetSet       = EReadOnly;
       
   385         break;
       
   386         
       
   387     case EMTPDevicePropCodeCompressionSetting:
       
   388         aInfo.iDataType     = EMTPTypeUINT8;
       
   389         aInfo.iFormFlag     = ENone;
       
   390         aInfo.iGetSet       = EReadOnly;
       
   391         break;
       
   392         
       
   393     case EMTPDevicePropCodeWhiteBalance:
       
   394         aInfo.iDataType     = EMTPTypeUINT16;
       
   395         aInfo.iFormFlag     = EEnumerationForm;
       
   396         aInfo.iGetSet       = EReadOnly;
       
   397         break;
       
   398         
       
   399     case EMTPDevicePropCodeRGBGain:
       
   400         aInfo.iDataType     = EMTPTypeString;
       
   401         aInfo.iFormFlag     = ENone;
       
   402         aInfo.iGetSet       = EReadOnly;
       
   403         break;
       
   404         
       
   405     case EMTPDevicePropCodeFNumber:
       
   406         aInfo.iDataType     = EMTPTypeUINT16;
       
   407         aInfo.iFormFlag     = EEnumerationForm;
       
   408         aInfo.iGetSet       = EReadOnly;
       
   409         break;
       
   410         
       
   411     case EMTPDevicePropCodeFocalLength:
       
   412         aInfo.iDataType     = EMTPTypeUINT32;
       
   413         aInfo.iFormFlag     = ENone;
       
   414         aInfo.iGetSet       = EReadOnly;
       
   415         break;
       
   416         
       
   417     case EMTPDevicePropCodeFocusDistance:
       
   418         aInfo.iDataType     = EMTPTypeUINT16;
       
   419         aInfo.iFormFlag     = ENone;
       
   420         aInfo.iGetSet       = EReadOnly;
       
   421         break;
       
   422         
       
   423     case EMTPDevicePropCodeFocusMode:
       
   424         aInfo.iDataType     = EMTPTypeUINT16;
       
   425         aInfo.iFormFlag     = EEnumerationForm;
       
   426         aInfo.iGetSet       = EReadOnly;
       
   427         break;
       
   428         
       
   429     case EMTPDevicePropCodeExposureMeteringMode:
       
   430         aInfo.iDataType     = EMTPTypeUINT16;
       
   431         aInfo.iFormFlag     = EEnumerationForm;
       
   432         aInfo.iGetSet       = EReadOnly;
       
   433         break;
       
   434         
       
   435     case EMTPDevicePropCodeFlashMode:
       
   436         aInfo.iDataType     = EMTPTypeUINT16;
       
   437         aInfo.iFormFlag     = EEnumerationForm;
       
   438         aInfo.iGetSet       = EReadOnly;
       
   439         break;
       
   440         
       
   441     case EMTPDevicePropCodeExposureTime:
       
   442         aInfo.iDataType     = EMTPTypeUINT32;
       
   443         aInfo.iFormFlag     = ENone;
       
   444         aInfo.iGetSet       = EReadOnly;
       
   445         break;
       
   446         
       
   447     case EMTPDevicePropCodeExposureProgramMode:
       
   448         aInfo.iDataType     = EMTPTypeUINT16;
       
   449         aInfo.iFormFlag     = EEnumerationForm;
       
   450         aInfo.iGetSet       = EReadOnly;
       
   451         break;
       
   452         
       
   453     case EMTPDevicePropCodeExposureIndex:
       
   454         aInfo.iDataType     = EMTPTypeUINT16;
       
   455         aInfo.iFormFlag     = ENone;
       
   456         aInfo.iGetSet       = EReadOnly;
       
   457         break;
       
   458         
       
   459     case EMTPDevicePropCodeExposureBiasCompensation:
       
   460         aInfo.iDataType     = EMTPTypeINT16;
       
   461         aInfo.iFormFlag     = ENone;
       
   462         aInfo.iGetSet       = EReadOnly;
       
   463         break;
       
   464         
       
   465     case EMTPDevicePropCodeDateTime:
       
   466         aInfo.iDataType     = EMTPTypeString;
       
   467         aInfo.iFormFlag     = ENone;
       
   468         aInfo.iGetSet       = EReadOnly;
       
   469         break;
       
   470         
       
   471     case EMTPDevicePropCodeCaptureDelay:
       
   472         aInfo.iDataType     = EMTPTypeUINT32;
       
   473         aInfo.iFormFlag     = ENone;
       
   474         aInfo.iGetSet       = EReadOnly;
       
   475         break;
       
   476         
       
   477     case EMTPDevicePropCodeStillCaptureMode:
       
   478         aInfo.iDataType     = EMTPTypeUINT16;
       
   479         aInfo.iFormFlag     = EEnumerationForm;
       
   480         aInfo.iGetSet       = EReadOnly;
       
   481         break;
       
   482         
       
   483     case EMTPDevicePropCodeContrast:
       
   484         aInfo.iDataType     = EMTPTypeUINT8;
       
   485         aInfo.iFormFlag     = ENone;
       
   486         aInfo.iGetSet       = EReadOnly;
       
   487         break;
       
   488         
       
   489     case EMTPDevicePropCodeSharpness:
       
   490         aInfo.iDataType     = EMTPTypeUINT8;
       
   491         aInfo.iFormFlag     = ENone;
       
   492         aInfo.iGetSet       = EReadOnly;
       
   493         break;
       
   494         
       
   495     case EMTPDevicePropCodeDigitalZoom:
       
   496         aInfo.iDataType     = EMTPTypeUINT8;
       
   497         aInfo.iFormFlag     = ENone;
       
   498         aInfo.iGetSet       = EReadOnly;
       
   499         break;
       
   500         
       
   501     case EMTPDevicePropCodeEffectMode:
       
   502         aInfo.iDataType     = EMTPTypeUINT16;
       
   503         aInfo.iFormFlag     = EEnumerationForm;
       
   504         aInfo.iGetSet       = EReadOnly;
       
   505         break;
       
   506         
       
   507     case EMTPDevicePropCodeBurstNumber:
       
   508         aInfo.iDataType     = EMTPTypeUINT16;
       
   509         aInfo.iFormFlag     = ENone;
       
   510         aInfo.iGetSet       = EReadOnly;
       
   511         break;
       
   512         
       
   513     case EMTPDevicePropCodeBurstInterval:
       
   514         aInfo.iDataType     = EMTPTypeUINT16;
       
   515         aInfo.iFormFlag     = ENone;
       
   516         aInfo.iGetSet       = EReadOnly;
       
   517         break;
       
   518         
       
   519     case EMTPDevicePropCodeTimelapseNumber:
       
   520         aInfo.iDataType     = EMTPTypeUINT16;
       
   521         aInfo.iFormFlag     = ENone;
       
   522         aInfo.iGetSet       = EReadOnly;
       
   523         break;
       
   524         
       
   525     case EMTPDevicePropCodeTimelapseInterval:
       
   526         aInfo.iDataType     = EMTPTypeUINT32;
       
   527         aInfo.iFormFlag     = ENone;
       
   528         aInfo.iGetSet       = EReadOnly;
       
   529         break;
       
   530         
       
   531     case EMTPDevicePropCodeFocusMeteringMode:
       
   532         aInfo.iDataType     = EMTPTypeUINT32;
       
   533         aInfo.iFormFlag     = EEnumerationForm;
       
   534         aInfo.iGetSet       = EReadOnly;
       
   535         break;
       
   536         
       
   537     case EMTPDevicePropCodeUploadURL:
       
   538         aInfo.iDataType     = EMTPTypeString;
       
   539         aInfo.iFormFlag     = ENone;
       
   540         aInfo.iGetSet       = EReadOnly;
       
   541         break;
       
   542         
       
   543     case EMTPDevicePropCodeArtist:
       
   544         aInfo.iDataType     = EMTPTypeString;
       
   545         aInfo.iFormFlag     = ENone;
       
   546         aInfo.iGetSet       = EReadOnly;
       
   547         break;
       
   548         
       
   549     case EMTPDevicePropCodeCopyrightInfo:
       
   550         aInfo.iDataType     = EMTPTypeString;
       
   551         aInfo.iFormFlag     = ENone;
       
   552         aInfo.iGetSet       = EReadOnly;
       
   553         break;
       
   554         
       
   555     case EMTPDevicePropCodeSynchronizationPartner:
       
   556         aInfo.iDataType     = EMTPTypeString;
       
   557         aInfo.iFormFlag     = ENone;
       
   558         aInfo.iGetSet       = EReadWrite;
       
   559         break;
       
   560         
       
   561     case EMTPDevicePropCodeDeviceFriendlyName:
       
   562         aInfo.iDataType     = EMTPTypeString;
       
   563         aInfo.iFormFlag     = ENone;
       
   564         aInfo.iGetSet       = EReadWrite;
       
   565         break;
       
   566         
       
   567     case EMTPDevicePropCodeVolume:
       
   568         aInfo.iDataType     = EMTPTypeUINT32;
       
   569         aInfo.iFormFlag     = ERangeForm;
       
   570         aInfo.iGetSet       = EReadWrite;
       
   571         break;
       
   572         
       
   573     case EMTPDevicePropCodeSupportedFormatsOrdered:
       
   574         aInfo.iDataType     = EMTPTypeUINT8;
       
   575         aInfo.iFormFlag     = ENone;
       
   576         aInfo.iGetSet       = EReadOnly;
       
   577         break;
       
   578         
       
   579     case EMTPDevicePropCodeDeviceIcon:
       
   580         aInfo.iDataType     = EMTPTypeAUINT8;
       
   581         aInfo.iFormFlag     = ENone;
       
   582         aInfo.iGetSet       = EReadOnly;
       
   583         break;
       
   584         
       
   585     case EMTPDevicePropCodePlaybackRate:
       
   586         aInfo.iDataType     = EMTPTypeINT32;
       
   587         aInfo.iFormFlag     = EEnumerationForm;
       
   588         aInfo.iGetSet       = EReadWrite;
       
   589         break;
       
   590         
       
   591     case EMTPDevicePropCodePlaybackObject:
       
   592         aInfo.iDataType     = EMTPTypeUINT32;
       
   593         aInfo.iFormFlag     = ENone;
       
   594         aInfo.iGetSet       = EReadWrite;
       
   595         break;
       
   596         
       
   597     case EMTPDevicePropCodePlaybackContainerIndex:
       
   598         aInfo.iDataType     = EMTPTypeUINT32;
       
   599         aInfo.iFormFlag     = ENone;
       
   600         aInfo.iGetSet       = EReadWrite;
       
   601         break;
       
   602         
       
   603     case EMTPDevicePropCodePlaybackPosition:
       
   604         aInfo.iDataType     = EMTPTypeUINT32;
       
   605         aInfo.iFormFlag     = ENone;
       
   606         aInfo.iGetSet       = EReadWrite;
       
   607         break;
       
   608         
       
   609     case EMTPDevicePropCodeSessionInitiatorVersionInfo:
       
   610         aInfo.iDataType     = EMTPTypeString;
       
   611         aInfo.iFormFlag     = ENone;
       
   612         aInfo.iGetSet       = EReadWrite;
       
   613         break;
       
   614         
       
   615     case EMTPDevicePropCodePerceivedDeviceType:
       
   616         aInfo.iDataType     = EMTPTypeUINT32;
       
   617         aInfo.iFormFlag     = ENone;
       
   618         aInfo.iGetSet       = EReadOnly;
       
   619         break;
       
   620         
       
   621     case EMTPDevicePropCodeFunctionalID:
       
   622         aInfo.iDataType     = EMTPTypeUINT128;
       
   623         aInfo.iFormFlag     = ENone;
       
   624         aInfo.iGetSet       = EReadWrite;
       
   625         break;
       
   626         
       
   627     case EMTPDevicePropCodeModelID:
       
   628         aInfo.iDataType     = EMTPTypeUINT128;
       
   629         aInfo.iFormFlag     = ENone;
       
   630         aInfo.iGetSet       = EReadOnly;
       
   631         break;
       
   632         
       
   633     case EMTPDevicePropCodeUseDeviceStage:
       
   634         aInfo.iDataType     = EMTPTypeUINT8;
       
   635         aInfo.iFormFlag     = ENone;
       
   636         aInfo.iGetSet       = EReadOnly;
       
   637         break;
       
   638         
       
   639     default:
       
   640         User::Leave(KErrNotSupported);
       
   641         break;
       
   642         }
       
   643     }
       
   644     
       
   645 const CMTPTypeCompoundBase::TElementInfo& CMTPTypeDevicePropDesc::ElementInfo(TInt aElementId) const
       
   646     {
       
   647     return iElementInfo[aElementId];
       
   648     }
       
   649     
       
   650 TBool CMTPTypeDevicePropDesc::ReadableElementL(TInt aElementId) const
       
   651     {
       
   652     TBool ret(ETrue);
       
   653     if (aElementId == EForm)
       
   654         {
       
   655         ret = HasFormField(Uint8L(EFormFlag));
       
   656         }
       
   657     return ret;
       
   658     }
       
   659     
       
   660 TBool CMTPTypeDevicePropDesc::WriteableElementL(TInt aElementId) const
       
   661     {
       
   662     TBool ret(EFalse);
       
   663 
       
   664     if (!iInitialised)
       
   665         {
       
   666         ret = ETrue;    
       
   667         }
       
   668     else
       
   669         {
       
   670         switch (aElementId)
       
   671             {
       
   672         case EGetSet:
       
   673         case EFactoryDefaultValue:
       
   674         case ECurrentValue:
       
   675             ret = ETrue;
       
   676             break;
       
   677 
       
   678         default:
       
   679             break;
       
   680             }   
       
   681         }
       
   682         
       
   683     return ret;
       
   684     }
       
   685 
       
   686 /*
       
   687 MTP DevicePropDesc dataset "pre-production" factory method for datasets
       
   688 which will be populated from an MTP write data stream. This method is used to 
       
   689 create a partially constructed MTP DevicePropDesc element dataset type prior to
       
   690 the construction characteristics being known. Construction of the element 
       
   691 dataset is completed on-the-fly as it is written to from an MTP write data 
       
   692 stream. A pointer to the data type is placed on the cleanup stack.
       
   693 @return A pointer to the ObjectPropList element dataset type. 
       
   694 Ownership IS transfered.
       
   695 @leave One of the system wide error codes, if unsuccessful.
       
   696 */
       
   697 CMTPTypeDevicePropDesc* CMTPTypeDevicePropDesc::NewLC()
       
   698     {
       
   699     CMTPTypeDevicePropDesc* self = new(ELeave) CMTPTypeDevicePropDesc();
       
   700     CleanupStack::PushL(self);
       
   701     TPropertyInfo info;
       
   702     PropertyInfoL(EMTPObjectPropCodeUndefined, info);
       
   703     self->ConstructL(EMTPObjectPropCodeUndefined, info, NULL);
       
   704     
       
   705     return self;
       
   706     }
       
   707 
       
   708 CMTPTypeDevicePropDesc::CMTPTypeDevicePropDesc() :
       
   709     CMTPTypeCompoundBase(KJustInTimeConstruction, KNumChunksWithoutForm),
       
   710     iElementInfo(iElementMetaData, ENumElements),
       
   711     iChunkFlat1(KFlat1ChunkSize, *this)
       
   712     {
       
   713     
       
   714     }
       
   715 
       
   716 void CMTPTypeDevicePropDesc::ConstructL(TUint16 aPropertyCode, const MMTPType* aForm)
       
   717     {
       
   718     TPropertyInfo info;
       
   719     PropertyInfoL(aPropertyCode, info);
       
   720     ConstructL(aPropertyCode, info, aForm);
       
   721     }
       
   722     
       
   723 void CMTPTypeDevicePropDesc::ConstructL(TUint16 aPropertyCode, const TPropertyInfo& aInfo, const MMTPType* aForm)
       
   724     {    
       
   725     // Construct the DevicePropDesc chunk sequence.
       
   726     for (TUint i(0); (i < ENumElements); i++)
       
   727         {
       
   728         const TElementInfo& element(iElementInfo[i]);
       
   729         if (ChunkCount() <= element.iChunkId)
       
   730             {
       
   731             MMTPType* chunk(NULL);
       
   732             switch (element.iChunkId)
       
   733                 {
       
   734             case EIdFlat1Chunk:
       
   735                 iChunkFlat1.OpenL();
       
   736                 chunk = &iChunkFlat1;
       
   737                 break;
       
   738                 
       
   739             case EIdDefaultValueChunk:
       
   740                 if (aInfo.iDataType != EMTPTypeUndefined)
       
   741                     {
       
   742                     iChunkDefaultValue.OpenL(aInfo.iDataType);
       
   743                     }
       
   744                 chunk = &iChunkDefaultValue;
       
   745                 break;
       
   746                 
       
   747             case EIdCurrentValueChunk:
       
   748                 if (aInfo.iDataType != EMTPTypeUndefined)
       
   749                     {
       
   750                     iChunkCurrentValue.OpenL(aInfo.iDataType);
       
   751                     }
       
   752                 chunk = &iChunkCurrentValue;
       
   753                 break;
       
   754                 
       
   755             case EIdFormFlagChunk:
       
   756                 chunk = &iChunkFormFlag;
       
   757                 break;
       
   758                 
       
   759             case EIdFormChunk:
       
   760                 iChunkForm.SetMeta(aInfo.iFormFlag, aInfo.iDataType);
       
   761                 if (HasFormField(aInfo.iFormFlag))
       
   762                     {
       
   763                     iChunkForm.OpenL(element.iType);
       
   764                     chunk = &iChunkForm;
       
   765                     }
       
   766                 break;
       
   767                 
       
   768             default:
       
   769                 Panic(EMTPTypeBoundsError);
       
   770                 break;
       
   771                 }
       
   772                     
       
   773             // Some chunks (i.e. FORM) are optional.
       
   774             if (chunk)
       
   775                 {
       
   776                 ChunkAppendL(*chunk);   
       
   777                 }
       
   778             }
       
   779         }
       
   780         
       
   781     // Set the construction values.
       
   782     SetUint16L(EDevicePropertyCode, aPropertyCode);
       
   783     SetUint16L(EDatatype, aInfo.iDataType);
       
   784     SetUint8L(EGetSet, aInfo.iGetSet);
       
   785     SetUint8L(EFormFlag, aInfo.iFormFlag);
       
   786     
       
   787     if (aForm)
       
   788         {
       
   789         if (!HasFormField(aInfo.iFormFlag))
       
   790             { 
       
   791             User::Leave(KMTPDataTypeInvalid);
       
   792             } 
       
   793         else
       
   794             {
       
   795             SetL(EForm, *aForm); 
       
   796             }
       
   797         }
       
   798     
       
   799     iInitialised = ETrue;
       
   800     }    
       
   801     
       
   802 TBool CMTPTypeDevicePropDesc::HasFormField(TUint8 aFormFlag) const
       
   803     {
       
   804     return (aFormFlag != ENone);
       
   805     }
       
   806     
       
   807 TInt CMTPTypeDevicePropDesc::UpdateWriteSequenceErr(TInt aErr)
       
   808     {
       
   809     iWriteSequenceErr = aErr;
       
   810     return iWriteSequenceErr;        
       
   811     }
       
   812     
       
   813 CMTPTypeDevicePropDesc::RMTPTypeDevicePropDescForm::RMTPTypeDevicePropDescForm() : 
       
   814     RMTPType()
       
   815     {
       
   816 
       
   817     }
       
   818 
       
   819 void CMTPTypeDevicePropDesc::RMTPTypeDevicePropDescForm::SetMeta(TUint8 aFormFlag, TUint aDataType)
       
   820     {
       
   821     iFormFlag = aFormFlag;
       
   822     iDataType = aDataType;
       
   823     }
       
   824 
       
   825 MMTPType* CMTPTypeDevicePropDesc::RMTPTypeDevicePropDescForm::CreateL(TUint aDataType)
       
   826     {
       
   827     if (aDataType != EMTPTypeReference)
       
   828         {
       
   829         User::Leave(KMTPDataTypeInvalid);
       
   830         }
       
   831         
       
   832     MMTPType* type(NULL);
       
   833     switch (iFormFlag)
       
   834         {
       
   835     case ERangeForm:
       
   836         type = CMTPTypeDevicePropDescRangeForm::NewL(iDataType);
       
   837         break;
       
   838         
       
   839     case EEnumerationForm:
       
   840         type = CMTPTypeDevicePropDescEnumerationForm::NewL(iDataType);
       
   841         break;
       
   842         
       
   843     default:
       
   844         // Invalid Form Flag.
       
   845         User::Leave(KMTPDataTypeInvalid);
       
   846         break;
       
   847         }
       
   848         
       
   849     return type;
       
   850     }
       
   851 
       
   852 void CMTPTypeDevicePropDesc::RMTPTypeDevicePropDescForm::Destroy(MMTPType* aType)
       
   853     {
       
   854     switch (iFormFlag)
       
   855         {
       
   856     case ERangeForm:
       
   857         delete static_cast<CMTPTypeDevicePropDescRangeForm*>(aType);
       
   858         break;
       
   859         
       
   860     case EEnumerationForm:
       
   861         delete static_cast<CMTPTypeDevicePropDescEnumerationForm*>(aType);
       
   862         break;
       
   863         
       
   864     default:
       
   865         // All other FORM types are managed by the base class.
       
   866         RMTPType::Destroy(aType);
       
   867         break;
       
   868         }
       
   869     }
       
   870 
       
   871 /**
       
   872 MTP DevicePropDesc Enumeration FORM dataset factory method. This method is used to 
       
   873 create an empty MTP DevicePropDesc FORM dataset of the specified Datatype. 
       
   874 @param aDataType The data type identifier datacode of the dataset.
       
   875 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
   876 transfered.
       
   877 @leave One of the system wide error codes, if unsuccessful.
       
   878 */     
       
   879 EXPORT_C CMTPTypeDevicePropDescEnumerationForm* CMTPTypeDevicePropDescEnumerationForm::NewL(TUint aDataType)
       
   880     {
       
   881     CMTPTypeDevicePropDescEnumerationForm* self = CMTPTypeDevicePropDescEnumerationForm::NewLC(aDataType);
       
   882     CleanupStack::Pop(self);
       
   883     return self;   
       
   884     }
       
   885 
       
   886 /**
       
   887 MTP DevicePropDesc Enumeration FORM dataset factory method. This method is used to 
       
   888 create an empty MTP DevicePropDesc FORM dataset of the specified Datatype. A 
       
   889 pointer to the data type is placed on the cleanup stack.
       
   890 @param aDataType The data type identifier datacode of the dataset.
       
   891 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
   892 transfered.
       
   893 @leave One of the system wide error codes, if unsuccessful.
       
   894 */   
       
   895 EXPORT_C CMTPTypeDevicePropDescEnumerationForm* CMTPTypeDevicePropDescEnumerationForm::NewLC(TUint aDataType)
       
   896     {
       
   897     CMTPTypeDevicePropDescEnumerationForm* self = new(ELeave) CMTPTypeDevicePropDescEnumerationForm(aDataType);
       
   898     CleanupStack::PushL(self);
       
   899     self->ConstructL();
       
   900     return self;
       
   901     }
       
   902 
       
   903 /**
       
   904 Destructor.
       
   905 */
       
   906 EXPORT_C CMTPTypeDevicePropDescEnumerationForm::~CMTPTypeDevicePropDescEnumerationForm()
       
   907     {
       
   908     TInt count(iChunksValue.Count());
       
   909     while (count--)
       
   910     	{
       
   911         iChunksValue[count].Close();
       
   912         }
       
   913     iChunksValue.Close();
       
   914     }
       
   915 
       
   916 /**
       
   917 Appends the specified value to the set of supported enumeration values.
       
   918 @param aValue The enumeration value to append.
       
   919 @leave One of the system wide error codes, if unsuccessful.
       
   920 @panic MTPDataTypes 3, if the source value type does not match the property 
       
   921 data type.
       
   922 */
       
   923 EXPORT_C void CMTPTypeDevicePropDescEnumerationForm::AppendSupportedValueL(const MMTPType& aValue)
       
   924     {
       
   925     __ASSERT_ALWAYS(aValue.Type() == iInfoValue.iType, Panic(EMTPTypeIdMismatch));
       
   926     
       
   927     // Increment NumberOfValues.
       
   928     const TUint index(iChunkNumberOfValues.Value());
       
   929     iChunkNumberOfValues.Set(index + 1);
       
   930     
       
   931     // Create and populate the SupportedValue chunk.
       
   932     AppendValueChunkL();
       
   933     SetL((KValueChunks + index), aValue);
       
   934     }
       
   935 
       
   936 /**
       
   937 Provides the NumberOfValues element value.
       
   938 */
       
   939 EXPORT_C TUint16 CMTPTypeDevicePropDescEnumerationForm::NumberOfValues() const
       
   940     {
       
   941     return iChunkNumberOfValues.Value();
       
   942     }
       
   943 
       
   944 /**
       
   945 Provides the SupportedValue element at the specified index.
       
   946 @param aIndex The index of the required value.
       
   947 @param aValue On successful completion, the requested value.
       
   948 @leave One of the system wide error codes, if unsuccessful.
       
   949 @panic MTPDataTypes 3, if the target value type does not match the property 
       
   950 data type.
       
   951 */
       
   952 EXPORT_C void CMTPTypeDevicePropDescEnumerationForm::SupportedValueL(TUint aIndex, MMTPType& aValue) const
       
   953     {
       
   954     __ASSERT_ALWAYS(aValue.Type() == iInfoValue.iType, Panic(EMTPTypeIdMismatch));
       
   955     GetL((KValueChunks + aIndex), aValue);
       
   956     }
       
   957     
       
   958 EXPORT_C TInt CMTPTypeDevicePropDescEnumerationForm::FirstWriteChunk(TPtr8& aChunk)
       
   959     {
       
   960     /* 
       
   961     Reset the type in preparation for the data stream, by deleting all
       
   962     except the first chunk.
       
   963     */
       
   964     for (TUint i(ChunkCount() - 1); (i >= (KNumberOfValuesChunk + 1)); i--)
       
   965         {
       
   966         ChunkRemove(i);
       
   967         }
       
   968     iChunksValue.Close();
       
   969     
       
   970     // Setup the write chunk pointer.
       
   971     TInt err(CMTPTypeCompoundBase::FirstWriteChunk(aChunk));
       
   972     switch (err)
       
   973         {
       
   974     case KMTPChunkSequenceCompletion:
       
   975         err = KErrNone;
       
   976         // Don't break, fall through to set the write sequence state.
       
   977         
       
   978     case KErrNone:
       
   979         // Set the write sequence state.
       
   980         iWriteSequenceState = EInProgress;
       
   981         break;
       
   982         
       
   983     default:
       
   984         break;
       
   985         }
       
   986         
       
   987     return  err;
       
   988     }
       
   989     
       
   990 EXPORT_C TInt CMTPTypeDevicePropDescEnumerationForm::NextWriteChunk(TPtr8& aChunk)
       
   991     {
       
   992     TInt err(CMTPTypeCompoundBase::NextWriteChunk(aChunk));
       
   993     if ((err == KMTPChunkSequenceCompletion) &&
       
   994         (iChunksValue.Count() < iChunkNumberOfValues.Value()))
       
   995         {
       
   996         err = KErrNone; 
       
   997         }
       
   998     return err;
       
   999     }
       
  1000  
       
  1001 EXPORT_C TUint CMTPTypeDevicePropDescEnumerationForm::Type() const
       
  1002     {
       
  1003     return EMTPTypeDevicePropDescEnumerationFormDataset;
       
  1004     }
       
  1005     
       
  1006 EXPORT_C TBool CMTPTypeDevicePropDescEnumerationForm::CommitRequired() const
       
  1007     {
       
  1008     return ETrue;
       
  1009     }
       
  1010 
       
  1011 EXPORT_C MMTPType* CMTPTypeDevicePropDescEnumerationForm::CommitChunkL(TPtr8& aChunk)
       
  1012     {
       
  1013     switch (iWriteSequenceState)
       
  1014         {
       
  1015     case EInProgress:
       
  1016         if (iChunksValue.Count() < iChunkNumberOfValues.Value())
       
  1017             {
       
  1018             AppendValueChunkL(); 
       
  1019             }
       
  1020         else
       
  1021             {
       
  1022             iWriteSequenceState = EIdle;
       
  1023             }
       
  1024         break;
       
  1025         
       
  1026     case EIdle:
       
  1027         // Completing the last element in the write sequence.
       
  1028         break;
       
  1029         
       
  1030     default:
       
  1031         Panic(EMTPTypeBadStorage);
       
  1032         break;
       
  1033         }
       
  1034         
       
  1035     if (CMTPTypeCompoundBase::CommitRequired())
       
  1036         {
       
  1037         CMTPTypeCompoundBase::CommitChunkL(aChunk);
       
  1038         }     
       
  1039     return NULL;
       
  1040     }
       
  1041  
       
  1042 const CMTPTypeCompoundBase::TElementInfo& CMTPTypeDevicePropDescEnumerationForm::ElementInfo(TInt aElementId) const
       
  1043     {
       
  1044     if (aElementId == KNumberOfValuesChunk)
       
  1045         {
       
  1046         return iInfoNumberOfValues;
       
  1047         }
       
  1048     else
       
  1049         {
       
  1050         __ASSERT_ALWAYS(((aElementId - KValueChunks) < iChunkNumberOfValues.Value()), Panic(EMTPTypeBoundsError));
       
  1051         iInfoValue.iChunkId = aElementId;
       
  1052         return iInfoValue; 
       
  1053         }
       
  1054     }
       
  1055 
       
  1056 TInt CMTPTypeDevicePropDescEnumerationForm::ValidateChunkCount() const
       
  1057     {
       
  1058     TInt ret(KErrNone);
       
  1059     if (NumberOfValues() != (ChunkCount() - 1))
       
  1060         {
       
  1061         ret = KMTPDataTypeInvalid;
       
  1062         }
       
  1063     return ret;
       
  1064     }
       
  1065 
       
  1066 CMTPTypeDevicePropDescEnumerationForm::CMTPTypeDevicePropDescEnumerationForm(TUint aDataType) :
       
  1067     CMTPTypeCompoundBase(KJustInTimeConstruction, KVariableChunkCount)
       
  1068     {
       
  1069     const CMTPTypeCompoundBase::TElementInfo KDefaultInfo = {0, EMTPTypeUndefined, {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}};
       
  1070     iInfoNumberOfValues         = KDefaultInfo; 
       
  1071     iInfoNumberOfValues.iType   = EMTPTypeUINT16;
       
  1072     iInfoValue                  = KDefaultInfo; 
       
  1073     iInfoValue.iType            = aDataType;
       
  1074     }
       
  1075 
       
  1076 void CMTPTypeDevicePropDescEnumerationForm::ConstructL()
       
  1077     {
       
  1078     ChunkAppendL(iChunkNumberOfValues);
       
  1079     }
       
  1080     
       
  1081 void CMTPTypeDevicePropDescEnumerationForm::AppendValueChunkL()
       
  1082     {
       
  1083     iChunksValue.AppendL(RMTPType());
       
  1084     
       
  1085     RMTPType& chunk(iChunksValue[iChunksValue.Count() - 1]);
       
  1086     chunk.OpenL(iInfoValue.iType);
       
  1087     ChunkAppendL(chunk);
       
  1088     }
       
  1089 
       
  1090 /**
       
  1091 MTP DevicePropDesc Range FORM dataset factory method. This method is used to 
       
  1092 create an empty MTP DevicePropDesc FORM dataset of the specified Datatype. 
       
  1093 @param aDataType The data type identifier datacode of the dataset.
       
  1094 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
  1095 transfered.
       
  1096 @leave One of the system wide error codes, if unsuccessful.
       
  1097 */   
       
  1098 EXPORT_C CMTPTypeDevicePropDescRangeForm* CMTPTypeDevicePropDescRangeForm::NewL(TUint aDataType)
       
  1099     {
       
  1100     CMTPTypeDevicePropDescRangeForm* self = CMTPTypeDevicePropDescRangeForm::NewLC(aDataType);
       
  1101     CleanupStack::Pop(self); 
       
  1102     return self;
       
  1103     }
       
  1104 
       
  1105 /**
       
  1106 MTP DevicePropDesc Range FORM dataset factory method. This method is used to 
       
  1107 create an empty MTP DevicePropDesc FORM dataset of the specified Datatype. A 
       
  1108 pointer to the data type is placed on the cleanup stack.
       
  1109 @param aDataType The data type identifier datacode of the dataset.
       
  1110 @return A pointer to the MTP DevicePropDesc dataset type. Ownership IS 
       
  1111 transfered.
       
  1112 @leave One of the system wide error codes, if unsuccessful.
       
  1113 */   
       
  1114 EXPORT_C CMTPTypeDevicePropDescRangeForm* CMTPTypeDevicePropDescRangeForm::NewLC(TUint aDataType)
       
  1115     {
       
  1116     CMTPTypeDevicePropDescRangeForm* self = new(ELeave) CMTPTypeDevicePropDescRangeForm(aDataType);
       
  1117     CleanupStack::PushL(self);
       
  1118     self->ConstructL();
       
  1119     return self;
       
  1120     }
       
  1121 
       
  1122 /**
       
  1123 Destructor.
       
  1124 */
       
  1125 EXPORT_C CMTPTypeDevicePropDescRangeForm::~CMTPTypeDevicePropDescRangeForm()
       
  1126     {
       
  1127     TInt count(iChunks.Count());
       
  1128     while (count--)
       
  1129         {
       
  1130         iChunks[count].Close();
       
  1131         }
       
  1132     iChunks.Reset();
       
  1133     }
       
  1134 
       
  1135 EXPORT_C TUint CMTPTypeDevicePropDescRangeForm::Type() const
       
  1136     {
       
  1137     return EMTPTypeDevicePropDescRangeFormDataset;
       
  1138     } 
       
  1139 
       
  1140 const CMTPTypeCompoundBase::TElementInfo& CMTPTypeDevicePropDescRangeForm::ElementInfo(TInt aElementId) const
       
  1141     {
       
  1142     __ASSERT_ALWAYS((aElementId < ENumElements), Panic(EMTPTypeBoundsError));
       
  1143     iInfoBuf.iChunkId = aElementId;
       
  1144     return iInfoBuf;    
       
  1145     }
       
  1146 
       
  1147 CMTPTypeDevicePropDescRangeForm::CMTPTypeDevicePropDescRangeForm(TUint aDataType) : 
       
  1148     CMTPTypeCompoundBase((!KJustInTimeConstruction), ENumElements), 
       
  1149     iDataType(aDataType)
       
  1150     {
       
  1151     const CMTPTypeCompoundBase::TElementInfo KDefaultInfo = {0, EMTPTypeReference, {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}};
       
  1152     iInfoBuf = KDefaultInfo;
       
  1153     }
       
  1154 
       
  1155 void CMTPTypeDevicePropDescRangeForm::ConstructL()
       
  1156     {
       
  1157     for (TUint i(0); (i < ENumElements); i++)   
       
  1158         {
       
  1159         iChunks.AppendL(RMTPType());
       
  1160         iChunks[i].OpenL(iDataType);
       
  1161         ChunkAppendL(iChunks[i]);
       
  1162         }
       
  1163     }