diff -r 000000000000 -r d0791faffa3f mtpfws/mtpfw/datatypes/src/cmtptypecompoundbase.cpp --- /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 +#include +#include + +#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(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(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(iChunks[info.iChunkId])); + chunk->SetInt8(aElementId, aData); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT8, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).Set(aData); + } + break; + + case EMTPTypeINT8: + { + TMTPTypeInt8* chunk(static_cast(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(iChunks[info.iChunkId])); + chunk->SetInt16(aElementId, aData); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT16, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).Set(aData); + } + break; + + case EMTPTypeINT16: + { + TMTPTypeInt16* chunk(static_cast(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(iChunks[info.iChunkId])); + chunk->SetInt32(aElementId, aData); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT32, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).Set(aData); + } + break; + + case EMTPTypeINT32: + { + TMTPTypeInt32* chunk(static_cast(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(iChunks[info.iChunkId])); + chunk->SetInt64(aElementId, aData); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT64, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).Set(aData); + } + break; + + case EMTPTypeINT64: + { + TMTPTypeInt64* chunk(static_cast(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(iChunks[info.iChunkId])); + chunk->SetUint8(aElementId, aData); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT8, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).Set(aData); + } + break; + + case EMTPTypeUINT8: + { + TMTPTypeUint8* chunk(static_cast(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(iChunks[info.iChunkId])); + chunk->SetUint16(aElementId, aData); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT16, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).Set(aData); + } + break; + + case EMTPTypeUINT16: + { + TMTPTypeUint16* chunk(static_cast(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(iChunks[info.iChunkId])); + chunk->SetUint32(aElementId, aData); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT32, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).Set(aData); + } + break; + + case EMTPTypeUINT32: + { + TMTPTypeUint32* chunk(static_cast(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(iChunks[info.iChunkId])); + chunk->SetUint64(aElementId, aData); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT64, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).Set(aData); + } + break; + + case EMTPTypeUINT64: + { + TMTPTypeUint64* chunk(static_cast(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(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeString, Panic(EMTPTypeIdMismatch)); + static_cast(chunk->Data()).SetL(aString); + } + break; + + case EMTPTypeString: + { + CMTPTypeString* chunk(static_cast(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(iChunks[info.iChunkId])); + ret = chunk->Int8(aElementId); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT8, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).Value(); + } + break; + + case EMTPTypeINT8: + { + TMTPTypeInt8* chunk(static_cast(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(iChunks[info.iChunkId])); + ret = chunk->Int16(aElementId); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT16, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).Value(); + } + break; + + case EMTPTypeINT16: + { + TMTPTypeInt16* chunk(static_cast(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(iChunks[info.iChunkId])); + ret = chunk->Int32(aElementId); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT32, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).Value(); + } + break; + + case EMTPTypeINT32: + { + TMTPTypeInt32* chunk(static_cast(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(iChunks[info.iChunkId])); + ret = chunk->Int64(aElementId); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeINT64, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).Value(); + } + break; + + case EMTPTypeINT64: + { + TMTPTypeInt64* chunk(static_cast(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(iChunks[info.iChunkId])); + ret = chunk->Uint8(aElementId); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT8, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).Value(); + } + break; + + case EMTPTypeUINT8: + { + TMTPTypeUint8* chunk(static_cast(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(iChunks[info.iChunkId])); + ret = chunk->Uint16(aElementId); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT16, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).Value(); + } + break; + + case EMTPTypeUINT16: + { + TMTPTypeUint16* chunk(static_cast(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(iChunks[info.iChunkId])); + ret = chunk->Uint32(aElementId); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT32, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).Value(); + } + break; + + case EMTPTypeUINT32: + { + TMTPTypeUint32* chunk(static_cast(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(iChunks[info.iChunkId])); + ret = chunk->Uint64(aElementId); + } + break; + + case EMTPTypeReference: + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeUINT64, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).Value(); + } + break; + + case EMTPTypeUINT64: + { + TMTPTypeUint64* chunk(static_cast(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(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeString, Panic(EMTPTypeIdMismatch)); + ret = static_cast(chunk->Data()).NumChars(); + } + break; + + case EMTPTypeString: + { + CMTPTypeString* chunk(static_cast(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(iChunks[info.iChunkId])); + return chunk->StringChars(); + } + else if (info.iType == EMTPTypeReference) + { + RMTPType* chunk(static_cast(iChunks[info.iChunkId])); + __ASSERT_DEBUG(chunk->Type() == EMTPTypeString, Panic(EMTPTypeIdMismatch)); + return static_cast(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; + }