mtpfws/mtpfw/datatypes/src/cmtptypecompoundbase.cpp
changeset 0 d0791faffa3f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpfws/mtpfw/datatypes/src/cmtptypecompoundbase.cpp	Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,1389 @@
+// 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/cmtptypecompoundbase.h>
+#include <mtp/cmtptypestring.h>
+#include <mtp/rmtptype.h>
+
+#include "mtpdatatypespanic.h"
+
+/**
+Destructor
+*/
+EXPORT_C CMTPTypeCompoundBase::~CMTPTypeCompoundBase()
+    {
+    Reset();    
+    }
+    
+/**
+Provides a copy of the specified element.
+@param aElementId The identifier of the requested element.
+@param aElement The MMTPType target data buffer.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the target buffer type does not match the requested
+element.
+*/
+EXPORT_C void CMTPTypeCompoundBase::GetL(TInt aElementId, MMTPType& aElement) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    if (info.iType == EMTPTypeFlat)
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->GetL(aElementId, aElement);
+        }
+    else
+        {
+        CopyL(*iChunks[info.iChunkId], aElement);
+        }
+    }
+
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aElement The MMTPType source data buffer.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/  
+EXPORT_C void CMTPTypeCompoundBase::SetL(TInt aElementId, const MMTPType& aElement)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    if (info.iType == EMTPTypeFlat)
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetL(aElementId, aElement);
+        }
+    else
+        {
+        CopyL(aElement, *iChunks[info.iChunkId]);
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aData The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetInt8L(TInt aElementId, TInt8 aData)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetInt8(aElementId, aData);
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT8, Panic(EMTPTypeIdMismatch));   
+        static_cast<TMTPTypeInt8&>(chunk->Data()).Set(aData);
+        }
+        break;
+        
+    case EMTPTypeINT8:
+        {
+        TMTPTypeInt8* chunk(static_cast<TMTPTypeInt8*>(iChunks[info.iChunkId]));
+        chunk->Set(aData);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aData The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetInt16L(TInt aElementId, TInt16 aData)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetInt16(aElementId, aData);
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT16, Panic(EMTPTypeIdMismatch)); 
+        static_cast<TMTPTypeInt16&>(chunk->Data()).Set(aData);
+        }
+        break;
+        
+    case EMTPTypeINT16:
+        {
+        TMTPTypeInt16* chunk(static_cast<TMTPTypeInt16*>(iChunks[info.iChunkId]));
+        chunk->Set(aData);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aData The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetInt32L(TInt aElementId, TInt32 aData)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetInt32(aElementId, aData);
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT32, Panic(EMTPTypeIdMismatch)); 
+        static_cast<TMTPTypeInt32&>(chunk->Data()).Set(aData);
+        }
+        break;
+        
+    case EMTPTypeINT32:
+        {
+        TMTPTypeInt32* chunk(static_cast<TMTPTypeInt32*>(iChunks[info.iChunkId]));
+        chunk->Set(aData);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aData The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetInt64L(TInt aElementId, TInt64 aData)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetInt64(aElementId, aData);
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT64, Panic(EMTPTypeIdMismatch)); 
+        static_cast<TMTPTypeInt64&>(chunk->Data()).Set(aData);
+        }
+        break;
+        
+    case EMTPTypeINT64:
+        {
+        TMTPTypeInt64* chunk(static_cast<TMTPTypeInt64*>(iChunks[info.iChunkId]));
+        chunk->Set(aData);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aData The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetUint8L(TInt aElementId, TUint8 aData)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetUint8(aElementId, aData);
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT8, Panic(EMTPTypeIdMismatch)); 
+        static_cast<TMTPTypeUint8&>(chunk->Data()).Set(aData);
+        }
+        break;
+        
+    case EMTPTypeUINT8:
+        {
+        TMTPTypeUint8* chunk(static_cast<TMTPTypeUint8*>(iChunks[info.iChunkId]));
+        chunk->Set(aData);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aData The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetUint16L(TInt aElementId, TUint16 aData)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetUint16(aElementId, aData);
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT16, Panic(EMTPTypeIdMismatch)); 
+        static_cast<TMTPTypeUint16&>(chunk->Data()).Set(aData);
+        }
+        break;
+        
+    case EMTPTypeUINT16:
+        {
+        TMTPTypeUint16* chunk(static_cast<TMTPTypeUint16*>(iChunks[info.iChunkId]));
+        chunk->Set(aData);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aData The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetUint32L(TInt aElementId, TUint32 aData)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetUint32(aElementId, aData);
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT32, Panic(EMTPTypeIdMismatch)); 
+        static_cast<TMTPTypeUint32&>(chunk->Data()).Set(aData);
+        }
+        break;
+        
+    case EMTPTypeUINT32:
+        {
+        TMTPTypeUint32* chunk(static_cast<TMTPTypeUint32*>(iChunks[info.iChunkId]));
+        chunk->Set(aData);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aData The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetUint64L(TInt aElementId, TUint64 aData)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        chunk->SetUint64(aElementId, aData);
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT64, Panic(EMTPTypeIdMismatch)); 
+        static_cast<TMTPTypeUint64&>(chunk->Data()).Set(aData);
+        }
+        break;
+        
+    case EMTPTypeUINT64:
+        {
+        TMTPTypeUint64* chunk(static_cast<TMTPTypeUint64*>(iChunks[info.iChunkId]));
+        chunk->Set(aData);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+    
+/**
+Updates the specified element.
+@param aElementId The identifier of the element to update.
+@param aString The source data.
+@leave KErrNotSupported, if the element is not writeable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source data type does not match the requested 
+element.
+*/    
+EXPORT_C void CMTPTypeCompoundBase::SetStringL(TInt aElementId, const TDesC& aString)
+    {
+    if (!WriteableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeString, Panic(EMTPTypeIdMismatch)); 
+        static_cast<CMTPTypeString&>(chunk->Data()).SetL(aString);
+        }
+        break;
+        
+    case EMTPTypeString:
+        {
+        CMTPTypeString* chunk(static_cast<CMTPTypeString*>(iChunks[info.iChunkId]));
+        chunk->SetL(aString);
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+    }
+
+
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TInt8 CMTPTypeCompoundBase::Int8L(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    TInt8 ret(0);
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        ret = chunk->Int8(aElementId); 
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT8, Panic(EMTPTypeIdMismatch)); 
+        ret = static_cast<TMTPTypeInt8&>(chunk->Data()).Value();
+        }
+        break;
+        
+    case EMTPTypeINT8:
+        {
+        TMTPTypeInt8* chunk(static_cast<TMTPTypeInt8*>(iChunks[info.iChunkId]));
+        ret = chunk->Value();
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+        
+    return ret;
+    }
+
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TInt16 CMTPTypeCompoundBase::Int16L(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    TInt16 ret(0);
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        ret = chunk->Int16(aElementId); 
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT16, Panic(EMTPTypeIdMismatch)); 
+        ret = static_cast<TMTPTypeInt16&>(chunk->Data()).Value();
+        }
+        break;
+        
+    case EMTPTypeINT16:
+        {
+        TMTPTypeInt16* chunk(static_cast<TMTPTypeInt16*>(iChunks[info.iChunkId]));
+        ret = chunk->Value();
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+        
+    return ret;
+    }
+
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TInt32 CMTPTypeCompoundBase::Int32L(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    TInt32 ret(0);
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        ret = chunk->Int32(aElementId); 
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT32, Panic(EMTPTypeIdMismatch)); 
+        ret = static_cast<TMTPTypeInt32&>(chunk->Data()).Value();
+        }
+        break;
+        
+    case EMTPTypeINT32:
+        {
+        TMTPTypeInt32* chunk(static_cast<TMTPTypeInt32*>(iChunks[info.iChunkId]));
+        ret = chunk->Value();
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+        
+    return ret;
+    }
+
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TInt64 CMTPTypeCompoundBase::Int64L(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    TInt64 ret(0);
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        ret = chunk->Int64(aElementId); 
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT64, Panic(EMTPTypeIdMismatch)); 
+        ret = static_cast<TMTPTypeInt64&>(chunk->Data()).Value();
+        }
+        break;
+        
+    case EMTPTypeINT64:
+        {
+        TMTPTypeInt64* chunk(static_cast<TMTPTypeInt64*>(iChunks[info.iChunkId]));
+        ret = chunk->Value();
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+        
+    return ret;
+    }
+
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TUint8 CMTPTypeCompoundBase::Uint8L(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    TUint8 ret(0);
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        ret = chunk->Uint8(aElementId); 
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT8, Panic(EMTPTypeIdMismatch)); 
+        ret = static_cast<TMTPTypeUint8&>(chunk->Data()).Value();
+        }
+        break;
+        
+    case EMTPTypeUINT8:
+        {
+        TMTPTypeUint8* chunk(static_cast<TMTPTypeUint8*>(iChunks[info.iChunkId]));
+        ret = chunk->Value();
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+        
+    return ret;
+    }
+
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TUint16 CMTPTypeCompoundBase::Uint16L(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    TUint16 ret(0);
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        ret = chunk->Uint16(aElementId); 
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT16, Panic(EMTPTypeIdMismatch)); 
+        ret = static_cast<TMTPTypeUint16&>(chunk->Data()).Value();
+        }
+        break;
+        
+    case EMTPTypeUINT16:
+        {
+        TMTPTypeUint16* chunk(static_cast<TMTPTypeUint16*>(iChunks[info.iChunkId]));
+        ret = chunk->Value();
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+        
+    return ret;
+    }
+
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TUint32 CMTPTypeCompoundBase::Uint32L(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+    
+    TUint32 ret(0);
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        ret = chunk->Uint32(aElementId); 
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT32, Panic(EMTPTypeIdMismatch)); 
+        ret = static_cast<TMTPTypeUint32&>(chunk->Data()).Value();
+        }
+        break;
+        
+    case EMTPTypeUINT32:
+        {
+        TMTPTypeUint32* chunk(static_cast<TMTPTypeUint32*>(iChunks[info.iChunkId]));
+        ret = chunk->Value();
+        }
+        break;
+        
+    case EMTPTypeUndefined:
+    default:
+        {
+        TMTPTypeUint32 chunk;
+        GetL(aElementId, chunk);
+        ret = chunk.Value();
+        }
+        break;
+        }
+        
+    return ret;
+    }
+
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TUint64 CMTPTypeCompoundBase::Uint64L(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+    
+    TUint64 ret(0);
+    
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeFlat:
+        {
+        RMTPTypeCompoundFlatChunk* chunk(static_cast<RMTPTypeCompoundFlatChunk*>(iChunks[info.iChunkId]));
+        ret = chunk->Uint64(aElementId); 
+        }
+        break;
+        
+    case EMTPTypeReference:
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT64, Panic(EMTPTypeIdMismatch)); 
+        ret = static_cast<TMTPTypeUint64&>(chunk->Data()).Value();
+        }
+        break;
+        
+    case EMTPTypeUINT64:
+        {
+        TMTPTypeUint64* chunk(static_cast<TMTPTypeUint64*>(iChunks[info.iChunkId]));
+        ret = chunk->Value();
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+        
+    return ret;
+    }
+    
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs. 
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C TUint8 CMTPTypeCompoundBase::StringNumCharsL(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    TUint8 ret(0);
+
+    const TElementInfo& info(ElementInfo(aElementId));
+    switch (info.iType)
+        {
+    case EMTPTypeReference:
+        {
+             
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeString, Panic(EMTPTypeIdMismatch));   
+        ret = static_cast<CMTPTypeString&>(chunk->Data()).NumChars();
+        }
+        break;
+        
+    case EMTPTypeString:
+        {
+        CMTPTypeString* chunk(static_cast<CMTPTypeString*>(iChunks[info.iChunkId]));
+        ret = chunk->NumChars();
+        }
+        break;
+        
+    default:
+        Panic(EMTPTypeIdMismatch);
+        break;
+        }
+        
+    return ret;
+    }
+   
+/**
+Provides the value of the specified element.
+@param aElementId The identifier of the requested element.
+@return The value of the element.
+@leave KErrNotSupported, if the element is not readable.
+@leave One of the system wide error code, if a processing error occurs.
+@panic MTPDataTypes 3, if the source buffer type does not match the requested 
+element.
+*/
+EXPORT_C const TDesC& CMTPTypeCompoundBase::StringCharsL(TInt aElementId) const
+    {
+    if (!ReadableElementL(aElementId))
+        {
+        User::Leave(KErrNotSupported);            
+        }
+        
+    const TElementInfo& info(ElementInfo(aElementId));
+    if (info.iType == EMTPTypeString)
+        {
+        CMTPTypeString* chunk(static_cast<CMTPTypeString*>(iChunks[info.iChunkId]));
+        return chunk->StringChars();
+        }
+    else if (info.iType == EMTPTypeReference)
+        {
+        RMTPType* chunk(static_cast<RMTPType*>(iChunks[info.iChunkId]));
+        __ASSERT_DEBUG(chunk->Type() == EMTPTypeString, Panic(EMTPTypeIdMismatch));   
+        return static_cast<CMTPTypeString&>(chunk->Data()).StringChars();
+        }
+    else
+        {
+        Panic(EMTPTypeIdMismatch);
+        }
+        
+    return KNullDesC;
+    }
+
+EXPORT_C TInt CMTPTypeCompoundBase::FirstReadChunk(TPtrC8& aChunk) const
+    {
+    TInt err(KErrNone);
+    aChunk.Set(NULL, 0);
+    
+    if (iChunks.Count() == 0)
+        {
+        err = KErrNotFound;            
+        }
+    else
+        {
+        iReadChunk = 0;
+        err = UpdateReadState(iChunks[iReadChunk]->FirstReadChunk(aChunk));
+        }
+    
+    return err;
+    }
+
+EXPORT_C TInt CMTPTypeCompoundBase::NextReadChunk(TPtrC8& aChunk) const
+    {
+    TInt err(KErrNotReady);
+    aChunk.Set(NULL, 0);
+    
+    switch (iReadSequenceState)
+        {
+    case EInProgressFirst:
+        err = UpdateReadState(iChunks[iReadChunk]->FirstReadChunk(aChunk));
+        break;
+        
+    case EInProgressNext:
+        err = UpdateReadState(iChunks[iReadChunk]->NextReadChunk(aChunk));
+        break;
+        
+    case EIdle:
+    default:
+        err = KErrNotReady;
+        break;
+        }
+    
+    return err;
+    }
+
+EXPORT_C TInt CMTPTypeCompoundBase::FirstWriteChunk(TPtr8& aChunk)
+    {
+    TInt err(KErrNone);
+    aChunk.Set(NULL, 0, 0);
+    
+    if (iChunks.Count() == 0)
+        {
+        err = KErrNotFound;            
+        }
+    else
+        {
+        iWriteChunk = 0;
+        err = UpdateWriteState(iChunks[iWriteChunk]->FirstWriteChunk(aChunk));
+        }
+    
+    return err;
+    }
+
+EXPORT_C TInt CMTPTypeCompoundBase::NextWriteChunk(TPtr8& aChunk)
+    {
+    TInt err(KErrNotReady);
+    aChunk.Set(NULL, 0, 0);
+    
+    switch (iWriteSequenceState)
+        {
+    case EInProgressFirst:
+        err = UpdateWriteState(iChunks[iWriteChunk]->FirstWriteChunk(aChunk));
+        break;
+        
+    case EInProgressNext:
+        err = UpdateWriteState(iChunks[iWriteChunk]->NextWriteChunk(aChunk));
+        break;
+        
+    case EIdle:
+    default:
+        err = KErrNotReady;
+        break;
+        }
+    
+    return err;
+    }
+
+EXPORT_C TInt CMTPTypeCompoundBase::NextWriteChunk(TPtr8& aChunk, TUint aDataLength)
+    {
+    TInt err(KErrNotReady);
+    aChunk.Set(NULL, 0, 0);
+    
+    switch (iWriteSequenceState)
+        {
+    case EInProgressFirst:
+        err = UpdateWriteState(iChunks[iWriteChunk]->FirstWriteChunk(aChunk, aDataLength));
+        break;
+        
+    case EInProgressNext:
+        err = UpdateWriteState(iChunks[iWriteChunk]->NextWriteChunk(aChunk, aDataLength));
+        break;
+        
+    case EIdle:
+    default:
+        err = KErrNotReady;
+        break;
+        }
+    
+    return err;
+    }
+
+EXPORT_C TUint64 CMTPTypeCompoundBase::Size() const
+    {
+    TUint64 size(0);
+    TUint numChunks(iChunks.Count());
+    for (TUint i(0); (i < numChunks); i++)
+        {
+        TUint64 chunkSize(iChunks[i]->Size());
+        size += chunkSize;
+        }
+        
+    return size;  
+    }
+
+EXPORT_C TUint CMTPTypeCompoundBase::Type() const
+    {
+    return EMTPTypeCompound;        
+    }
+
+EXPORT_C TBool CMTPTypeCompoundBase::CommitRequired() const
+    {
+    return ETrue;
+    }
+
+EXPORT_C MMTPType* CMTPTypeCompoundBase::CommitChunkL(TPtr8& aChunk)
+    {        
+    MMTPType *chunk(iChunks[iWriteChunk]);
+    MMTPType* res = NULL;
+    if (chunk->CommitRequired())
+        {
+        res = chunk->CommitChunkL(aChunk);
+        }
+        
+    if (iJustInTimeConstruction)
+        {
+        UpdateWriteState(iWriteErr);   
+        }
+    
+    if (iWriteSequenceState == EInProgressFirst)
+        {
+        iWriteChunk++;            
+        }
+    return res;
+    }
+    
+    
+EXPORT_C TInt CMTPTypeCompoundBase::Validate() const
+    {
+    const TUint count(ChunkCount());
+    TInt ret(KMTPDataTypeInvalid);
+    if (iExpectedChunkCount == KVariableChunkCount)
+        {
+        ret = ValidateChunkCount();
+        }
+    else if (count == iExpectedChunkCount)
+        {
+        /*
+        The element count is correct. Verify that the last element was 
+        correctly received.
+        */
+        ret = KErrNone;
+        }
+        
+    if (ret == KErrNone)
+        {
+        /*
+        The element count is correct. Verify that the last element was 
+        correctly received.
+        */
+        ret = iChunks[count - 1]->Validate();
+        }
+    return ret;
+    }
+
+/**
+Constructor.
+@param aJustInTimeConstruction This flag indicates that the derived class uses 
+a just-in-time construction technique when constructing iteself from a write
+data stream. Typically this is used for types whose final structure is dependant
+upon data contained within the data stream itself, e.g. a dataset with an 
+element whose data type is determined by meta data which precedes the element 
+in the data stream.
+@param aExpectedChunkCount This flag is used by the derived class to indicate 
+the number of chunks which make up the compound type. A value of 
+KVariableChunkCount indicates that the type is of variable rather than fixed 
+length (e.g. a list of elements). If KVariableChunkCount is specified then the
+derived class's ValidChunkCount method is invoked when the compound type is
+validated (@see ValidateChunkCount).
+@see Validate
+@see ValidateChunkCount
+@see KVariableChunkCount
+*/
+EXPORT_C CMTPTypeCompoundBase::CMTPTypeCompoundBase(TBool aJustInTimeConstruction, TUint aExpectedChunkCount) :
+    iExpectedChunkCount(aExpectedChunkCount),
+    iJustInTimeConstruction(aJustInTimeConstruction)
+    {
+        
+    }
+
+/**
+Appends the specified data chunk to the compound type's sequence of chunks.
+@param aChunk The chunk to be appended.
+*/
+EXPORT_C void CMTPTypeCompoundBase::ChunkAppendL(const MMTPType& aChunk)
+    {
+    iChunks.AppendL(&aChunk);
+    }
+
+/**
+Removes the chunk at the specified position in the chunk sequence.
+@param aChunkId The index of the chunk in in the chunk sequence.
+*/
+EXPORT_C void CMTPTypeCompoundBase::ChunkRemove(TUint aChunkId) 
+    {
+    iChunks.Remove(aChunkId);
+    }
+    
+/**
+Provides the number of discrete data chunks of which the compound type is
+composed.
+@return The number of discrete data chunks components which make up the 
+compound type.
+*/
+EXPORT_C TUint CMTPTypeCompoundBase::ChunkCount() const
+    {
+    return iChunks.Count();   
+    }
+    
+/**
+Resets the compound base, removing all data chunk references.
+*/
+EXPORT_C void CMTPTypeCompoundBase::Reset()
+    {
+    iChunks.Close();    
+    }
+    
+/**
+Sets the expected chunk count. This flag is used by the derived class to 
+indicate the number of chunks which make up the compound type. A value of 
+KVariableChunkCount indicates that the type is of variable rather than fixed 
+length (e.g. a list of elements). If KVariableChunkCount is specified then the
+derived class's ValidChunkCount method is invoked when the compound type is
+validated (@see ValidateChunkCount).
+@param aExpectedChunkCount The new expected chunk count.
+*/
+EXPORT_C void CMTPTypeCompoundBase::SetExpectedChunkCount(TUint aExpectedChunkCount)
+    {
+    iExpectedChunkCount = aExpectedChunkCount;
+    }
+    
+/**
+Indicates if the specified element can be read from.
+@param aElementId The identifier of the requested element.
+@return ETrue if the element is readable, otherwise EFalse.
+*/
+EXPORT_C TBool CMTPTypeCompoundBase::ReadableElementL(TInt /*aElementId*/) const
+    {
+    return ETrue;        
+    }
+    
+/**
+Indicates if the specified element can be written to.
+@param aElementId The identifier of the requested element.
+@return ETrue if the element is writeable, otherwise EFalse.
+*/
+EXPORT_C TBool CMTPTypeCompoundBase::WriteableElementL(TInt /*aElementId*/) const
+    {
+    return ETrue;        
+    }
+    
+TInt CMTPTypeCompoundBase::UpdateReadState(TInt aErr) const
+    {
+    TInt ret(aErr);
+    
+    switch (aErr)
+        {
+    case KMTPChunkSequenceCompletion:
+        if (++iReadChunk < iChunks.Count())
+            {
+            iReadSequenceState = EInProgressFirst;
+            ret = KErrNone;                    
+            }
+        else
+            {
+            iReadSequenceState = EIdle;                 
+            }
+        break;
+        
+    case KErrNone:
+        iReadSequenceState = EInProgressNext;
+        break;
+        
+    default:
+        break;
+        }
+        
+    return ret;
+    }
+    
+/**
+Validates that the number of chunks making up the compound type is valid. This
+method is invoked on variable length compound types by the default @see Valid 
+implementation.
+@see Valid
+@see KVariableChunkCount
+*/
+EXPORT_C TInt CMTPTypeCompoundBase::ValidateChunkCount() const
+    {
+    return KMTPDataTypeInvalid;
+    }
+
+TInt CMTPTypeCompoundBase::UpdateWriteState(TInt aErr)
+    {
+    TInt ret(aErr);
+    
+    iWriteErr = aErr;
+    switch (iWriteErr)
+        {
+    case KMTPChunkSequenceCompletion:
+        if ((iWriteChunk + 1) < iChunks.Count())
+            {
+            iWriteSequenceState = EInProgressFirst;
+            ret = KErrNone;
+            }
+        else
+            {
+            iWriteSequenceState = EIdle;                 
+            }
+        break;
+        
+    case KErrNone:
+        iWriteSequenceState = EInProgressNext;
+        break;
+        
+    default:
+        break;
+        }
+        
+    return ret;
+    }
+
+/**
+Constructor.
+@param aSize The size (in bytes) of the flat data chunk.
+@param aParent The compound data type of which the flat data chunk is a component.
+*/
+EXPORT_C CMTPTypeCompoundBase::RMTPTypeCompoundFlatChunk::RMTPTypeCompoundFlatChunk(TUint aSize, CMTPTypeCompoundBase& aParent) :
+    iSize(aSize),
+    iParent(&aParent)
+    {
+
+    }
+
+/**
+Releases the storage assigned to the flat data chunk.
+*/
+EXPORT_C void CMTPTypeCompoundBase::RMTPTypeCompoundFlatChunk::Close()
+    {
+    iBuffer.Close(); 
+    }
+
+/**
+Allocates storage for the flat data chunk.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+EXPORT_C void CMTPTypeCompoundBase::RMTPTypeCompoundFlatChunk::OpenL()
+    {
+    iBuffer.CreateMaxL(iSize);
+    iBuffer.FillZ();
+    SetBuffer(iBuffer);
+    }
+    
+EXPORT_C TUint CMTPTypeCompoundBase::RMTPTypeCompoundFlatChunk::Type() const
+    {
+    return EMTPTypeFlat;
+    }
+
+const TMTPTypeFlatBase::TElementInfo& CMTPTypeCompoundBase::RMTPTypeCompoundFlatChunk::ElementInfo(TInt aElementId) const
+    {
+    return iParent->ElementInfo(aElementId).iFlatChunkInfo;
+    }