--- /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;
+ }