mtpfws/mtpfw/datatypes/src/cmtptypeinterdependentpropdesc.cpp
changeset 0 d0791faffa3f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpfws/mtpfw/datatypes/src/cmtptypeinterdependentpropdesc.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,478 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+/**
+ @file
+ @publishedPartner
+*/
+
+#include <mtp/cmtptypeobjectpropdesc.h>
+#include <mtp/cmtptypeinterdependentpropdesc.h>
+#include <mtp/mtpdatatypeconstants.h>
+
+#include "mtpdatatypespanic.h"
+
+// Dataset constants    
+const TUint CMTPTypeInterdependentPropDesc::KNumberOfInterdependenciesChunk(0);
+const TUint CMTPTypeInterdependentPropDesc::KInterdependentPropertiesChunks(1);
+
+const TUint CMTPTypeInterdependentProperties::KNumberOfPropDescsChunk(0);
+const TUint CMTPTypeInterdependentProperties::KObjectPropDescChunks(1);
+
+/**
+MTP InterdependentPropDesc dataset factory method. This method is used to create an 
+empty MTP InterdependentPropDesc dataset. 
+@return A pointer to the MTP InterdependentPropDesc dataset type. Ownership IS 
+transfered.
+@leave One of the system wide error codes, if unsuccessful.
+*/ 
+EXPORT_C CMTPTypeInterdependentPropDesc* CMTPTypeInterdependentPropDesc::NewL()
+    {
+    CMTPTypeInterdependentPropDesc* self = CMTPTypeInterdependentPropDesc::NewLC(); 
+    CleanupStack::Pop(self); 
+    return self;  
+    }
+
+/**
+MTP InterdependentPropDesc dataset factory method. This method is used to create an 
+empty MTP InterdependentPropDesc dataset. A pointer to the data type is placed on the
+cleanup stack.
+@return A pointer to the MTP InterdependentPropDesc dataset type. Ownership IS 
+transfered.
+@leave One of the system wide error codes, if unsuccessful.
+*/ 
+EXPORT_C CMTPTypeInterdependentPropDesc* CMTPTypeInterdependentPropDesc::NewLC()
+    {
+    CMTPTypeInterdependentPropDesc* self = new(ELeave) CMTPTypeInterdependentPropDesc();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+/**
+Destructor.
+*/
+EXPORT_C CMTPTypeInterdependentPropDesc::~CMTPTypeInterdependentPropDesc()
+    {
+    iChunksInterdependentProperties.ResetAndDestroy();
+    }
+
+/**
+Appends the specified InterdependentPropDesc value quadruple to the InterdependentPropDesc. 
+Ownership of the specified InterdependentPropDesc value quadruple is passed to the 
+InterdependentPropDesc.
+@param aElement The InterdependentPropDesc value quadruple to append. Ownership IS
+transferred.
+@leave One of the system wide error codes, if unsuccessful.
+*/
+EXPORT_C void CMTPTypeInterdependentPropDesc::AppendL(CMTPTypeInterdependentProperties* aInterdependentProperties)
+    {
+    // Increment NumberOfElements.
+    const TUint index(iChunkNumberOfInterdependencies.Value());
+    iChunkNumberOfInterdependencies.Set(index + 1);
+    
+    // Append the element.
+    AppendElementChunkL(aInterdependentProperties);
+    }
+
+/**
+Provides the NumberOfElements element value.
+*/
+EXPORT_C TUint32 CMTPTypeInterdependentPropDesc::NumberOfInterdependencies() const
+    {
+    return iChunkNumberOfInterdependencies.Value();
+    }
+
+/**
+Provides a non-const reference to the InterdependentPropDesc value quadruple element at
+the specified index.
+@param aIndex The index of the required element.
+@param aValue On successful completion, a non-const reference to the requested
+element.
+@leave One of the system wide error codes, if unsuccessful.
+*/
+EXPORT_C CMTPTypeInterdependentProperties& CMTPTypeInterdependentPropDesc::InterdependentProperties(TUint aIndex) const
+    {
+    return *iChunksInterdependentProperties[aIndex];
+    }
+
+EXPORT_C TInt CMTPTypeInterdependentPropDesc::FirstWriteChunk(TPtr8& aChunk)
+    {   
+    /* 
+    Reset the type in preparation for the data stream, by deleting all
+    except the first chunk.
+    */
+    for (TUint i(ChunkCount() - 1); (i >= (KNumberOfInterdependenciesChunk + 1)); i--)
+        {
+        ChunkRemove(i);
+        }
+    iChunksInterdependentProperties.ResetAndDestroy();
+    
+    // Setup the write chunk pointer.
+    TInt err(UpdateWriteSequenceErr(CMTPTypeCompoundBase::FirstWriteChunk(aChunk)));
+    switch (err)
+        {
+    case KMTPChunkSequenceCompletion:
+        err = KErrNone;
+        // Don't break, fall through to set the write sequence state.
+        
+    case KErrNone:
+        // Set the write sequence state.
+        iWriteSequenceState = EInProgress;
+        break;
+        
+    default:
+        break;
+        }
+        
+    return  err;
+    }
+    
+EXPORT_C TInt CMTPTypeInterdependentPropDesc::NextWriteChunk(TPtr8& aChunk)
+    {
+    TInt err(KMTPChunkSequenceCompletion);
+    
+    if (iWriteSequenceState != EIdle)
+       {
+       err = UpdateWriteSequenceErr(CMTPTypeCompoundBase::NextWriteChunk(aChunk));
+       if ((iWriteSequenceErr == KMTPChunkSequenceCompletion) && (iWriteSequenceState != EIdle))
+           {
+           err = KErrNone;
+           }   
+       }    
+    return err;
+       
+    }
+
+EXPORT_C TUint CMTPTypeInterdependentPropDesc::Type() const
+    {
+    return EMTPTypeInterdependentPropDescDataset;
+    }
+
+EXPORT_C TBool CMTPTypeInterdependentPropDesc::CommitRequired() const
+    {
+    return ETrue;
+    }
+
+EXPORT_C MMTPType* CMTPTypeInterdependentPropDesc::CommitChunkL(TPtr8& aChunk)
+    {
+    if (iWriteSequenceErr == KMTPChunkSequenceCompletion)
+        {
+        switch (iWriteSequenceState)
+            {
+        case EInProgress:
+            if ((iChunkNumberOfInterdependencies.Value()) && 
+                (iChunksInterdependentProperties.Count() < iChunkNumberOfInterdependencies.Value()))
+                {
+                // Allocate the next element chunk.
+                CMTPTypeInterdependentProperties* element = CMTPTypeInterdependentProperties::NewLC();
+                AppendElementChunkL(element);
+                CleanupStack::Pop(element);
+                }
+            else
+                {
+                iWriteSequenceState = EIdle;
+                }
+            break;
+            
+        case EIdle:
+            // Completing the last element in the write sequence.
+            break;
+            
+        default:
+            Panic(EMTPTypeBadStorage);
+            break;
+            }
+        }
+        
+    if (CMTPTypeCompoundBase::CommitRequired())
+        {
+        CMTPTypeCompoundBase::CommitChunkL(aChunk);
+        }     
+    return NULL;
+    }
+ 
+const CMTPTypeCompoundBase::TElementInfo& CMTPTypeInterdependentPropDesc::ElementInfo(TInt aElementId) const
+    {
+    if (aElementId == KNumberOfInterdependenciesChunk)
+        {
+        return iInfoNumberOfInterdependencies;
+        }
+    else
+        {
+        __ASSERT_ALWAYS(((aElementId - KInterdependentPropertiesChunks) < iChunkNumberOfInterdependencies.Value()), Panic(EMTPTypeBoundsError));
+        iInfoInterdependentProperties.iChunkId = aElementId;
+        return iInfoInterdependentProperties; 
+        }
+    }
+
+TInt CMTPTypeInterdependentPropDesc::ValidateChunkCount() const
+    {
+    TInt ret(KErrNone);
+    if (NumberOfInterdependencies() != (ChunkCount() - 1))
+        {
+        ret = KMTPDataTypeInvalid;
+        }
+    return ret;
+    }
+
+CMTPTypeInterdependentPropDesc::CMTPTypeInterdependentPropDesc() :
+    CMTPTypeCompoundBase(KJustInTimeConstruction, KVariableChunkCount)
+    {
+    const CMTPTypeCompoundBase::TElementInfo KDefaultInfo = {0, EMTPTypeUndefined, {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}};
+    iInfoNumberOfInterdependencies          = KDefaultInfo; 
+    iInfoNumberOfInterdependencies.iType    = EMTPTypeUINT32;
+    iInfoInterdependentProperties           = KDefaultInfo; 
+    iInfoInterdependentProperties.iType     = EMTPTypeInterdependentPropDescElementDataset;
+    }
+
+void CMTPTypeInterdependentPropDesc::ConstructL()
+    {
+    ChunkAppendL(iChunkNumberOfInterdependencies);
+    }
+    
+void CMTPTypeInterdependentPropDesc::AppendElementChunkL(CMTPTypeInterdependentProperties* aElement)
+    {
+    iChunksInterdependentProperties.AppendL(aElement);
+    ChunkAppendL(*aElement);
+    }
+    
+TInt CMTPTypeInterdependentPropDesc::UpdateWriteSequenceErr(TInt aErr)
+    {
+    iWriteSequenceErr = aErr;
+    return iWriteSequenceErr;        
+    }
+
+/**
+MTP InterdependentPropDesc array element dataset factory method. This method is
+used to create an empty MTP InterdependentPropDesc array element dataset. 
+@return A pointer to the MTP InterdependentPropDesc array element dataset type.
+Ownership IS transfered.
+@leave One of the system wide error codes, if unsuccessful.
+*/ 
+EXPORT_C CMTPTypeInterdependentProperties* CMTPTypeInterdependentProperties::NewL()
+    {
+    CMTPTypeInterdependentProperties* self = CMTPTypeInterdependentProperties::NewLC(); 
+    CleanupStack::Pop(self);
+    return self;  
+    }
+
+/**
+MTP InterdependentPropDesc array element dataset factory method. This method is
+used to create an empty MTP InterdependentPropDesc array element dataset. A 
+pointer to the data type is placed on the cleanup stack.
+@return A pointer to the MTP InterdependentPropDesc array element dataset type. 
+Ownership IS transfered.
+@leave One of the system wide error codes, if unsuccessful.
+*/ 
+EXPORT_C CMTPTypeInterdependentProperties* CMTPTypeInterdependentProperties::NewLC()
+    {
+    CMTPTypeInterdependentProperties* self = new(ELeave) CMTPTypeInterdependentProperties();
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+/**
+Destructor.
+*/
+EXPORT_C CMTPTypeInterdependentProperties::~CMTPTypeInterdependentProperties()
+    {
+    iChunksObjectPropDesc.ResetAndDestroy();
+    }
+
+/**
+Appends the specified ObjectPropDesc dataset to the InterdependentPropDesc 
+array element array. Ownership of the specified ObjectPropDesc dataset is 
+passed to the InterdependentPropDesc array element array.
+@param aElement The ObjectPropDesc dataset to append. Ownership IS transferred.
+@leave One of the system wide error codes, if unsuccessful.
+*/
+EXPORT_C void CMTPTypeInterdependentProperties::AppendL(CMTPTypeObjectPropDesc* aElement)
+    {
+    // Increment NumberOfElements.
+    const TUint index(iChunkNumberOfPropDescs.Value());
+    iChunkNumberOfPropDescs.Set(index + 1);
+    
+    // Append the element.
+    AppendElementChunkL(aElement);
+    }
+
+/**
+Provides the NumberOfPropDescs element value.
+*/
+EXPORT_C TUint32 CMTPTypeInterdependentProperties::NumberOfPropDescs() const
+    {
+    return iChunkNumberOfPropDescs.Value();
+    }
+
+/**
+Provides a non-const reference to the InterdependentPropDesc value quadruple element at
+the specified index.
+@param aIndex The index of the required element.
+@param aValue On successful completion, a non-const reference to the requested
+element.
+@leave One of the system wide error codes, if unsuccessful.
+*/
+EXPORT_C CMTPTypeObjectPropDesc& CMTPTypeInterdependentProperties::ObjectPropDesc(TUint aIndex) const
+    {
+    return *iChunksObjectPropDesc[aIndex];
+    }
+
+EXPORT_C TInt CMTPTypeInterdependentProperties::FirstWriteChunk(TPtr8& aChunk)
+    {   
+    /* 
+    Reset the type in preparation for the data stream, by deleting all
+    except the first chunk.
+    */
+    for (TUint i(ChunkCount() - 1); (i >= (KNumberOfPropDescsChunk + 1)); i--)
+        {
+        ChunkRemove(i);
+        }
+    iChunksObjectPropDesc.ResetAndDestroy();
+    
+    // Setup the write chunk pointer.
+    TInt err(UpdateWriteSequenceErr(CMTPTypeCompoundBase::FirstWriteChunk(aChunk)));
+    switch (err)
+        {
+    case KMTPChunkSequenceCompletion:
+        err = KErrNone;
+        // Don't break, fall through to set the write sequence state.
+        
+    case KErrNone:
+        // Set the write sequence state.
+        iWriteSequenceState = EInProgress;
+        break;
+        
+    default:
+        break;
+        }
+        
+    return  err;
+    }
+    
+EXPORT_C TInt CMTPTypeInterdependentProperties::NextWriteChunk(TPtr8& aChunk)
+    {
+    TInt err(KMTPChunkSequenceCompletion);
+    
+    if (iWriteSequenceState != EIdle)
+       {
+       err = UpdateWriteSequenceErr(CMTPTypeCompoundBase::NextWriteChunk(aChunk));
+       if ((iWriteSequenceErr == KMTPChunkSequenceCompletion) && (iWriteSequenceState != EIdle))
+           {
+           err = KErrNone;
+           }   
+       }    
+    return err;
+    }
+
+EXPORT_C TUint CMTPTypeInterdependentProperties::Type() const
+    {
+    return EMTPTypeInterdependentPropDescElementDataset;
+    }
+
+EXPORT_C TBool CMTPTypeInterdependentProperties::CommitRequired() const
+    {
+    return ETrue;
+    }
+
+EXPORT_C MMTPType* CMTPTypeInterdependentProperties::CommitChunkL(TPtr8& aChunk)
+    {
+    if (iWriteSequenceErr == KMTPChunkSequenceCompletion)
+        {
+        switch (iWriteSequenceState)
+            {
+        case EInProgress:
+            if ( ( iChunkNumberOfPropDescs.Value() ) &&
+            (iChunksObjectPropDesc.Count() < iChunkNumberOfPropDescs.Value()))
+                {
+                // Allocate the next element chunk.
+                CMTPTypeObjectPropDesc* element = CMTPTypeObjectPropDesc::NewLC();
+                AppendElementChunkL(element);
+                CleanupStack::Pop(element); 
+                }
+            else
+                {
+                iWriteSequenceState = EIdle;
+                }
+            break;
+            
+        case EIdle:
+            // Completing the last element in the write sequence.
+            break;
+            
+        default:
+            Panic(EMTPTypeBadStorage);
+            break;
+            }
+        }
+        
+    if (CMTPTypeCompoundBase::CommitRequired())
+        {
+        CMTPTypeCompoundBase::CommitChunkL(aChunk);
+        }     
+    return NULL;
+    }
+ 
+const CMTPTypeCompoundBase::TElementInfo& CMTPTypeInterdependentProperties::ElementInfo(TInt aElementId) const
+    {
+    if (aElementId == KNumberOfPropDescsChunk)
+        {
+        return iInfoNumberOfPropDescs;
+        }
+    else
+        {
+        __ASSERT_ALWAYS(((aElementId - KObjectPropDescChunks) < iChunkNumberOfPropDescs.Value()), Panic(EMTPTypeBoundsError));
+        iInfoObjectPropDesc.iChunkId = aElementId;
+        return iInfoObjectPropDesc; 
+        }
+    }
+
+TInt CMTPTypeInterdependentProperties::ValidateChunkCount() const
+    {
+    TInt ret(KErrNone);
+    if (NumberOfPropDescs() != (ChunkCount() - 1))
+        {
+        ret = KMTPDataTypeInvalid;
+        }
+    return ret;
+    }
+
+CMTPTypeInterdependentProperties::CMTPTypeInterdependentProperties() :
+    CMTPTypeCompoundBase(KJustInTimeConstruction, KVariableChunkCount)
+    {
+    const CMTPTypeCompoundBase::TElementInfo KDefaultInfo = {0, EMTPTypeUndefined, {EMTPTypeUndefined, KMTPNotApplicable,  KMTPNotApplicable}};
+    iInfoNumberOfPropDescs          = KDefaultInfo; 
+    iInfoNumberOfPropDescs.iType    = EMTPTypeUINT32;
+    iInfoObjectPropDesc             = KDefaultInfo; 
+    iInfoObjectPropDesc.iType       = EMTPTypeInterdependentPropDescElementDataset;
+    }
+
+void CMTPTypeInterdependentProperties::ConstructL()
+    {
+    ChunkAppendL(iChunkNumberOfPropDescs);
+    }
+    
+void CMTPTypeInterdependentProperties::AppendElementChunkL(CMTPTypeObjectPropDesc* aElement)
+    {
+    iChunksObjectPropDesc.AppendL(aElement);
+    ChunkAppendL(*aElement);
+    }
+    
+TInt CMTPTypeInterdependentProperties::UpdateWriteSequenceErr(TInt aErr)
+    {
+    iWriteSequenceErr = aErr;
+    return iWriteSequenceErr;        
+    }