mtpfws/mtpfw/datatypes/src/cmtptypeserviceobjpropextnform.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/cmtptypeserviceobjpropextnform.h>
       
    22 #include <mtp/mtpdatatypeconstants.h>
       
    23 #include <mtp/mtpprotocolconstants.h>
       
    24 #include <mtp/cmtptypestring.h>
       
    25 
       
    26 #include "mtpdatatypespanic.h"
       
    27 
       
    28 // Dataset constants
       
    29 const TUint CMTPTypeServiceObjPropExtnForm::KFlat1ChunkSize(20);
       
    30 const TUint CMTPTypeServiceObjPropExtnForm::KFlat2ChunkSize(1);
       
    31 const TUint CMTPTypeServiceObjPropExtnForm::KNumChunksWithoutForm(EIdFlat2Chunk + 1);
       
    32 const TUint CMTPTypeServiceObjPropExtnForm::KNumChunksWithForm(EIdFormChunk + 1);
       
    33 
       
    34 //Dataset element metadata    
       
    35 const CMTPTypeCompoundBase::TElementInfo CMTPTypeServiceObjPropExtnForm::iElementMetaData[CMTPTypeServiceObjPropExtnForm::ENumElements] = 
       
    36     {
       
    37         {EIdFlat1Chunk,       EMTPTypeFlat,       {EMTPTypeUINT128,    0,                 KMTPTypeUINT128Size}},   // EPKNamespace
       
    38         {EIdFlat1Chunk,       EMTPTypeFlat,       {EMTPTypeUINT32,    16,                 KMTPTypeUINT32Size}},    // EPKeyID
       
    39         {EIdNameChunk,        EMTPTypeString,     {EMTPTypeString, KMTPNotApplicable,     KMTPNotApplicable}},     // EPropertyName
       
    40         {EIdFlat2Chunk,       EMTPTypeFlat,       {EMTPTypeUINT8,     0,                  KMTPTypeUINT8Size}},     // EFormFlag
       
    41         {EIdFormChunk,        EMTPTypeReference,  {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}},     // EForm
       
    42     };
       
    43 
       
    44 
       
    45 /**
       
    46 MTP Service Object Property Extension FORM dataset factory method. This method is used to 
       
    47 create an empty MTP Service Object Property Extension FORM  of the specified Datatype. 
       
    48 @param aDataType The data type identifier datacode of the object property.
       
    49 @return A pointer to the form type. Ownership IS 
       
    50 transfered.
       
    51 @leave One of the system wide error codes, if unsuccessful.
       
    52 */ 
       
    53 EXPORT_C  CMTPTypeServiceObjPropExtnForm* CMTPTypeServiceObjPropExtnForm::NewL( const TUint aDataType )
       
    54     {
       
    55     CMTPTypeServiceObjPropExtnForm* self = CMTPTypeServiceObjPropExtnForm::NewLC( aDataType );
       
    56     CleanupStack::Pop(self); 
       
    57     return self;
       
    58     }
       
    59 /**
       
    60 MTP DevicePropDesc  Service Object Property Extension FORM  factory method. This method is used to 
       
    61 create an empty MTP Service Object Property Extension FORM  of the specified Datatype. 
       
    62 @param aDataType The data type identifier datacode of the the object property.
       
    63 @return A pointer to the form type. Ownership IS 
       
    64 transfered.
       
    65 @leave One of the system wide error codes, if unsuccessful.
       
    66 */
       
    67 EXPORT_C  CMTPTypeServiceObjPropExtnForm* CMTPTypeServiceObjPropExtnForm::NewLC( const TUint aDataType )
       
    68     {
       
    69     CMTPTypeServiceObjPropExtnForm* self = new(ELeave) CMTPTypeServiceObjPropExtnForm( aDataType );
       
    70     CleanupStack::PushL(self);
       
    71     TMTPTypeGuid KUndefinedNamespace(0,0);
       
    72     TUint KPKeyID(0);
       
    73     TBuf<1> KName;
       
    74     self->ConstructL( KUndefinedNamespace, KPKeyID, KName, CMTPTypeObjectPropDesc::ENone, NULL );
       
    75     
       
    76     return self;
       
    77     }
       
    78 
       
    79    
       
    80 EXPORT_C  CMTPTypeServiceObjPropExtnForm* CMTPTypeServiceObjPropExtnForm::NewL( const TUint aDataType, const TMTPTypeGuid  aPKNamespace, const TUint aPKID, const TDesC& aName, const TUint8 aFormFlag, const MMTPType* aForm)
       
    81     {
       
    82     CMTPTypeServiceObjPropExtnForm* self = CMTPTypeServiceObjPropExtnForm::NewLC( aDataType, aPKNamespace, aPKID, aName, aFormFlag, aForm );
       
    83     CleanupStack::Pop(self); 
       
    84     return self;
       
    85     }
       
    86    
       
    87   
       
    88 EXPORT_C  CMTPTypeServiceObjPropExtnForm* CMTPTypeServiceObjPropExtnForm::NewLC( const TUint aDataType, const TMTPTypeGuid  aPKNamespace, const TUint aPKID, const TDesC& aName, const TUint8 aFormFlag, const MMTPType* aForm)
       
    89     {
       
    90     CMTPTypeServiceObjPropExtnForm* self = new(ELeave) CMTPTypeServiceObjPropExtnForm(aDataType);
       
    91     CleanupStack::PushL(self);
       
    92     self->ConstructL( aPKNamespace, aPKID, aName, aFormFlag, aForm );
       
    93     return self;
       
    94     }
       
    95 
       
    96 
       
    97 /**
       
    98 Destructor.
       
    99 */
       
   100 EXPORT_C CMTPTypeServiceObjPropExtnForm::~CMTPTypeServiceObjPropExtnForm()
       
   101     {
       
   102     iChunkFlat1.Close();
       
   103     delete iChunkName;
       
   104     iChunkFlat2.Close();
       
   105     iChunkForm.Close();
       
   106     }
       
   107 
       
   108 CMTPTypeServiceObjPropExtnForm::CMTPTypeServiceObjPropExtnForm(const TUint aDataType) : 
       
   109     CMTPTypeCompoundBase((KJustInTimeConstruction), KNumChunksWithoutForm),
       
   110     iElementInfo(iElementMetaData, ENumElements),
       
   111     iChunkFlat1(KFlat1ChunkSize, *this),
       
   112     iChunkFlat2(KFlat2ChunkSize, *this),
       
   113     iDataType(aDataType),
       
   114     iInitialised(EFalse)
       
   115     {
       
   116 
       
   117     }
       
   118 
       
   119 EXPORT_C TUint CMTPTypeServiceObjPropExtnForm::Type() const
       
   120     {
       
   121     return EMTPTypeServiceObjPropExtnFormDataset;
       
   122     } 
       
   123 
       
   124 
       
   125 
       
   126 EXPORT_C TInt CMTPTypeServiceObjPropExtnForm::FirstWriteChunk(TPtr8& aChunk)
       
   127     {
       
   128     /* 
       
   129     Reset the type in preparation for the data stream, by deleting all
       
   130     except the first chunk.
       
   131     */
       
   132     for (TUint i(ChunkCount() - 1); i > EIdFlat1Chunk ; i--)
       
   133       {
       
   134       ChunkRemove(i);
       
   135       }
       
   136       
       
   137     // Setup the write chunk pointer.
       
   138     TInt err(UpdateWriteSequenceErr(CMTPTypeCompoundBase::FirstWriteChunk(aChunk)));
       
   139     switch (err)
       
   140       {
       
   141     case KMTPChunkSequenceCompletion:
       
   142       err = KErrNone;
       
   143       // Don't break, fall through to set the write sequence state.
       
   144       
       
   145     case KErrNone:
       
   146       // Set the write sequence state.
       
   147       iWriteSequenceState = EFlat1Chunk; 
       
   148       
       
   149       /* 
       
   150       Set the write sequence completion state. Initially assume that the 
       
   151       extension form has a FORM field. If no FORM field is subsequently
       
   152       detected in the write data stream then the completion state is 
       
   153       adjusted accordingly.
       
   154       */
       
   155       iWriteSequenceCompletionState = EFormChunk;
       
   156       break;
       
   157       
       
   158     default:
       
   159       break;
       
   160       }
       
   161       
       
   162     return  err;
       
   163     }
       
   164 
       
   165 EXPORT_C TInt CMTPTypeServiceObjPropExtnForm::NextWriteChunk(TPtr8& aChunk)
       
   166     {
       
   167     TInt err(KMTPChunkSequenceCompletion);
       
   168      
       
   169      if (iWriteSequenceState != EIdle)
       
   170          {
       
   171          err = UpdateWriteSequenceErr(CMTPTypeCompoundBase::NextWriteChunk(aChunk));
       
   172          if ((iWriteSequenceErr == KMTPChunkSequenceCompletion) && (iWriteSequenceState != EIdle))
       
   173              {
       
   174              err = KErrNone;
       
   175              }   
       
   176          }    
       
   177      return err;
       
   178     }
       
   179 
       
   180 EXPORT_C TBool CMTPTypeServiceObjPropExtnForm::CommitRequired() const
       
   181     {
       
   182     return ETrue;
       
   183     }
       
   184 
       
   185 EXPORT_C MMTPType* CMTPTypeServiceObjPropExtnForm::CommitChunkL(TPtr8& aChunk)
       
   186     {
       
   187     if (iWriteSequenceErr == KMTPChunkSequenceCompletion)
       
   188         {
       
   189         switch (iWriteSequenceState)
       
   190             {
       
   191         case EFlat1Chunk:     
       
   192             delete iChunkName;
       
   193             iChunkName = CMTPTypeString::NewL();
       
   194             ChunkAppendL(*iChunkName);
       
   195             break;
       
   196             
       
   197         case ENameChunk:
       
   198             ChunkAppendL(iChunkFlat2);
       
   199             break;
       
   200             
       
   201         case EFlat2Chunk: 
       
   202             {
       
   203             iChunkForm.Close();
       
   204             TUint8 flag(Uint8L(EFormFlag));
       
   205             iChunkForm.SetMeta(flag, iDataType);
       
   206             if (HasFormField(flag))
       
   207                 {
       
   208                 iChunkForm.OpenL(iElementInfo[EForm].iType);
       
   209                 ChunkAppendL(iChunkForm);
       
   210                 SetExpectedChunkCount(KNumChunksWithForm);
       
   211                 }
       
   212             else
       
   213                 {
       
   214                 // Adjust the write sequence completion state.            
       
   215                 iWriteSequenceCompletionState = EFlat2Chunk;
       
   216                 }   
       
   217             }
       
   218             break;
       
   219             
       
   220         case EFormChunk:
       
   221         case EIdle:
       
   222         default:
       
   223             break;
       
   224             }
       
   225         
       
   226     if ( (iWriteSequenceState != EIdle ) && (iWriteSequenceState < iWriteSequenceCompletionState) )
       
   227         {
       
   228         iWriteSequenceState++;
       
   229         }
       
   230     else
       
   231         {
       
   232         iWriteSequenceState = EIdle;
       
   233         }
       
   234     }
       
   235         
       
   236     if (CMTPTypeCompoundBase::CommitRequired())
       
   237         {
       
   238         CMTPTypeCompoundBase::CommitChunkL(aChunk);
       
   239         }
       
   240     return NULL;
       
   241     }
       
   242 
       
   243 TBool CMTPTypeServiceObjPropExtnForm::HasFormField(TUint8 aFormFlag) const
       
   244     {
       
   245     return ((aFormFlag != CMTPTypeObjectPropDesc::EDateTimeForm) && (aFormFlag != CMTPTypeObjectPropDesc::ENone) && (aFormFlag != CMTPTypeObjectPropDesc::EObjectIDForm) );
       
   246     }
       
   247 
       
   248 TInt CMTPTypeServiceObjPropExtnForm::UpdateWriteSequenceErr(TInt aErr)
       
   249     {
       
   250     iWriteSequenceErr = aErr;
       
   251     return iWriteSequenceErr;        
       
   252     }
       
   253 
       
   254 TBool CMTPTypeServiceObjPropExtnForm::ReadableElementL(TInt aElementId) const
       
   255     {
       
   256     __ASSERT_ALWAYS((aElementId < ENumElements), Panic(EMTPTypeBoundsError));
       
   257     
       
   258     TBool ret(ETrue);
       
   259     if (aElementId == EForm)
       
   260         {
       
   261         ret = HasFormField(Uint8L(EFormFlag));
       
   262         }
       
   263     return ret;
       
   264     }
       
   265     
       
   266 TBool CMTPTypeServiceObjPropExtnForm::WriteableElementL(TInt aElementId) const
       
   267     {  
       
   268     __ASSERT_ALWAYS((aElementId < ENumElements), Panic(EMTPTypeBoundsError));
       
   269     
       
   270     if (!iInitialised)
       
   271         {
       
   272         return ETrue;    
       
   273         }
       
   274     
       
   275     if (aElementId == EForm)
       
   276         return EFalse;
       
   277     
       
   278     return ETrue;
       
   279     }
       
   280 
       
   281 const CMTPTypeCompoundBase::TElementInfo& CMTPTypeServiceObjPropExtnForm::ElementInfo(TInt aElementId) const
       
   282     {
       
   283     __ASSERT_ALWAYS((aElementId < ENumElements), Panic(EMTPTypeBoundsError));
       
   284     
       
   285     return iElementInfo[aElementId];  
       
   286     }   
       
   287 
       
   288 void CMTPTypeServiceObjPropExtnForm::ConstructL( const TMTPTypeGuid  aPKNamespace, const TUint aPKID, const TDesC& aName, const TUint8 aFormFlag, const MMTPType* aForm )
       
   289     {  
       
   290     for (TUint i(0); (i < ENumElements); i++)
       
   291        {
       
   292        const TElementInfo& element(iElementInfo[i]);
       
   293        if (ChunkCount() <= element.iChunkId)
       
   294            {
       
   295            MMTPType* chunk(NULL);
       
   296            switch (element.iChunkId)
       
   297                {
       
   298            case EIdFlat1Chunk:
       
   299                iChunkFlat1.OpenL();
       
   300                chunk = &iChunkFlat1;
       
   301                break;
       
   302                
       
   303            case EIdNameChunk:
       
   304                iChunkName = CMTPTypeString::NewL();
       
   305                chunk = iChunkName;
       
   306                break;
       
   307                
       
   308            case EIdFlat2Chunk:
       
   309                iChunkFlat2.OpenL();
       
   310                chunk = &iChunkFlat2;
       
   311                break;
       
   312                
       
   313            case EIdFormChunk:
       
   314                iChunkForm.SetMeta(aFormFlag, iDataType);
       
   315                if (HasFormField(aFormFlag))
       
   316                    {
       
   317                    iChunkForm.OpenL(element.iType);
       
   318                    chunk = &iChunkForm;
       
   319                    SetExpectedChunkCount(KNumChunksWithForm);
       
   320                    }
       
   321                break;
       
   322                
       
   323            default:
       
   324                Panic(EMTPTypeBoundsError);
       
   325                break;
       
   326                }
       
   327                    
       
   328            if (chunk)
       
   329                {
       
   330                ChunkAppendL(*chunk);   
       
   331                }
       
   332            }
       
   333        }      
       
   334     // Set the construction values.
       
   335     SetL( EPKeyNamespace, aPKNamespace );
       
   336     SetUint32L( EPKeyID, aPKID );
       
   337     SetStringL( EPropertyName, aName );
       
   338     SetUint8L(EFormFlag, aFormFlag);
       
   339     
       
   340     if (aForm)
       
   341         {
       
   342         if (!HasFormField(aFormFlag))
       
   343             { 
       
   344             User::Leave(KMTPDataTypeInvalid);
       
   345             } 
       
   346         else
       
   347             {
       
   348             SetL(EForm, *aForm); 
       
   349             }
       
   350         }
       
   351     
       
   352     iInitialised = ETrue;
       
   353     }