diff -r 000000000000 -r d0791faffa3f mtpfws/mtpfw/datatypes/src/cmtptypearray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtpfws/mtpfw/datatypes/src/cmtptypearray.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,979 @@ +// 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 "mtpdatatypespanic.h" + +// Array type constants. +const TUint KMTPNumElementsLen(sizeof(TUint32)); +const TUint KMTPNumElementsOffset(0); +const TUint KMTPFirstElementOffset(KMTPNumElementsLen); +const TUint KMTPGranularity(8); + +/** +MTP array data type factory method. This method is used to create an empty MTP +array. +@param aElementType The MTP type identifier of the elements contained in the +array. +@param aElementSize The size (in bytes) of the elements contained in the array. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aElementType, TUint aElementSize) + { + return NewL(EMTPTypeArray, aElementType, aElementSize); + } + +/** +MTP array data type factory method. This method is used to create an empty MTP +array. A pointer to the MTP array data type is placed on the cleanup stack. +@param aElementType The MTP type identifier of the elements contained in the +array. +@param aElementSize The size (in bytes) of the elements which contained in +array. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aElementType, TUint aElementSize) + { + return CMTPTypeArray::NewLC(EMTPTypeArray, aElementType, aElementSize); + } + +/** +MTP array data type factory method. This method is used to create an empty MTP +array of the specified MTP array type. +@param aArrayType The MTP type identifier to be assigned to the array. +@param aElementType The MTP type identifier of the elements contained in the +array. +@param aElementSize The size (in bytes) of the elements contained in the array. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aArrayType, TInt aElementType, TUint aElementSize) + { + CMTPTypeArray* self = NewLC(aArrayType, aElementType, aElementSize); + CleanupStack::Pop(self); + return self; + } + +/** +MTP array data type factory method. This method is used to create an empty MTP +array of the specified MTP array type. A pointer to the MTP array data type is +placed on the cleanup stack. +@param aArrayType The MTP type identifier to be assigned to the array. +@param aElementType The MTP type identifier of the elements contained in the +array. +@param aElementSize The size (in bytes) of the elements which contained in +array. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aArrayType, TInt aElementType, TUint aElementSize) + { + CMTPTypeArray* self = new(ELeave) CMTPTypeArray(aArrayType, aElementType, aElementSize); + CleanupStack::PushL(self); + self->ConstructL(KMTPGranularity); + return self; + } + +/** +MTP simple data type array factory method. This method is used to create +an empty MTP array of the specified MTP simple data type. +@param aArrayType The array data type indentifier datacode. This must be in +the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aArrayType) + { + CMTPTypeArray* self = NewLC(aArrayType); + CleanupStack::Pop(self); + return self; + } + +/** +MTP simple data type array factory method. This method is used to create +an MTP array of the specified MTP simple data type with the specified element +content. +@param aArrayType The array data type indentifier datacode. This must be in +the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@param aElements The initial set of element values. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aArrayType, const RArray& aElements) + { + CMTPTypeArray* self = NewLC(aArrayType, aElements); + CleanupStack::Pop(self); + return self; + } + +/** +MTP simple data type array factory method. This method is used to create +an MTP array of the specified MTP simple data type with the specified element +content. +@param aArrayType The array data type indentifier datacode. This must be in +the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@param aElements The initial set of element values. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aArrayType, const RArray& aElements) + { + CMTPTypeArray* self = NewLC(aArrayType, aElements); + CleanupStack::Pop(self); + return self; + } + +/** +MTP AINT64 array factory method. This method is used to create an MTP AINT64 +array with the specified element content. +@param aElements The initial set of element values. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(const RArray& aElements) + { + CMTPTypeArray* self = NewLC(aElements); + CleanupStack::Pop(self); + return self; + } + +/** +MTP AUINT64 array factory method. This method is used to create an MTP AINT64 +array with the specified element content. +@param aElements The initial set of element values. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(const RArray& aElements) + { + CMTPTypeArray* self = NewLC(aElements); + CleanupStack::Pop(self); + return self; + } + +/** +MTP simple data type array factory method. This method is used to create +an empty MTP array of the specified MTP simple data type. A pointer to the MTP +array data type is placed on the cleanup stack. +@param aArrayType The array data type indentifier datacode. This must be in +the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aArrayType) + { + TInt type(aArrayType); + TUint size(0); + SimpleArrayTypeMetaDataL(aArrayType, type, size); + CMTPTypeArray* self = new(ELeave) CMTPTypeArray(aArrayType, type, size); + CleanupStack::PushL(self); + self->ConstructL(KMTPGranularity); + return self; + } + +/** +MTP simple data type array factory method. This method is used to create +an MTP array of the specified MTP simple data type with the specified element +content. A pointer to the MTP array data type is placed on the cleanup stack. +@param aArrayType The array data type indentifier datacode. This must be in +the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@param aElements The initial set of element values. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aArrayType, const RArray& aElements) + { + TInt type(aArrayType); + TUint size(0); + SimpleArrayTypeMetaDataL(aArrayType, type, size); + CMTPTypeArray* self = new(ELeave) CMTPTypeArray(aArrayType, type, size); + CleanupStack::PushL(self); + + TUint count(aElements.Count()); + self->ConstructL(count); + + for (TUint i(0); (i < count); i++) + { + self->AppendIntL(aElements[i]); + } + + return self; + } + +/** +MTP simple data type array factory method. This method is used to create +an MTP array of the specified MTP simple data type with the specified element +content. A pointer to the MTP array data type is placed on the cleanup stack. +@param aArrayType The array data type indentifier datacode. This must be in +the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@param aElements The initial set of element values. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aArrayType, const RArray& aElements) + { + TInt type(aArrayType); + TUint size(0); + SimpleArrayTypeMetaDataL(aArrayType, type, size); + CMTPTypeArray* self = new(ELeave) CMTPTypeArray(aArrayType, type, size); + CleanupStack::PushL(self); + + TUint count(aElements.Count()); + self->ConstructL(count); + + for (TUint i(0); (i < count); i++) + { + self->AppendUintL(aElements[i]); + } + + return self; + } + +/** +MTP AINT64 array factory method. This method is used to create an MTP AINT64 +array with the specified element content. A pointer to the MTP array data type +is placed on the cleanup stack. +@param aElements The initial set of element values. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(const RArray& aElements) + { + TInt type(EMTPTypeINT64); + TUint size(0); + SimpleArrayTypeMetaDataL(EMTPTypeAINT64, type, size); + CMTPTypeArray* self = new(ELeave) CMTPTypeArray(EMTPTypeAINT64, type, size); + CleanupStack::PushL(self); + + TUint count(aElements.Count()); + self->ConstructL(count); + + for (TUint i(0); (i < count); i++) + { + self->AppendInt64L(aElements[i]); + } + + return self; + } + +/** +MTP AUINT64 array factory method. This method is used to create an MTP AUINT64 +array with the specified element content. A pointer to the MTP array data type +is placed on the cleanup stack. +@param aElements The initial set of element values. +@return A pointer to an empty MTP array data type. Ownership IS transfered. +@leave KErrArgument, if aArrayType is not in the range +EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType. +@leave One of the system wide error codes, if a processing failure occurs. +*/ +EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(const RArray& aElements) + { + TInt type(EMTPTypeUINT64); + TUint size(0); + SimpleArrayTypeMetaDataL(EMTPTypeAUINT64, type, size); + CMTPTypeArray* self = new(ELeave) CMTPTypeArray(EMTPTypeAUINT64, type, size); + CleanupStack::PushL(self); + + TUint count(aElements.Count()); + self->ConstructL(count); + + for (TUint i(0); (i < count); i++) + { + self->AppendUint64L(aElements[i]); + } + + return self; + } + +/** +Destructor +*/ +EXPORT_C CMTPTypeArray::~CMTPTypeArray() + { + iBuffer.Close(); + } + +/** +Provides the MTP identifier of the elements contained in the array. +@return The MTP identifier of the elements contained in the array. +*/ +EXPORT_C TInt CMTPTypeArray::ElementType() const + { + return iElementType; + } + +/** +Provides the number of elements contained in the MTP array. +@return The number of elements contained in the MTP array. +*/ +EXPORT_C TUint32 CMTPTypeArray::NumElements() const + { + return *(reinterpret_cast(&iBuffer[KMTPNumElementsOffset])); + } + +/** +Appends the specified element to the end of the MTP array. +@param aElement The element to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP type of the elements +contained in the array. +*/ +EXPORT_C void CMTPTypeArray::AppendL(const MMTPType& aElement) + { + __ASSERT_ALWAYS((aElement.Type() == iElementType), Panic(EMTPTypeIdMismatch)); + const TUint index(NumElements()); + TUint32 numElements(index + 1); + + if (iBuffer.MaxLength() < BufferSize(numElements)) + { + ReAllocBufferL(numElements); + } + + TBool complete(EFalse); + TUint offset(Offset(index)); + TPtrC8 src; + const TUint startOffset(offset); + + TInt err(aElement.FirstReadChunk(src)); + while (((err == KMTPChunkSequenceCompletion) || (err == KErrNone)) && (!complete)) + { + __ASSERT_ALWAYS(((offset - startOffset) <= iElementSize), Panic(EMTPTypeSizeMismatch)); + memcpy(&iBuffer[offset], src.Ptr(), src.Length()); + offset += src.Length(); + + complete = (err == KMTPChunkSequenceCompletion); + if (!complete) + { + err = aElement.NextReadChunk(src); + } + } + + if (err != KMTPChunkSequenceCompletion) + { + User::Leave(err); + } + + SetNumElements(numElements); + } + +/** +Appends the specified elements to the end of the MTP array. The array +element type MUST be one of the MTP INT8, INT16, or INT32 types. +@param aElements The elements to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::AppendL(const RArray& aElements) + { + TUint count(aElements.Count()); + for (TUint i(0); (i < count); i++) + { + AppendIntL(aElements[i]); + } + } + +/** +Appends the specified elements to the end of the MTP array. The array +element type MUST be one of the MTP UINT8, UINT16, or UINT32 types. +@param aElements The elements to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::AppendL(const RArray& aElements) + { + TUint count(aElements.Count()); + for (TUint i(0); (i < count); i++) + { + AppendUintL(aElements[i]); + } + } + +/** +Appends the specified elements to the end of the MTP array. The array +element type MUST be of the MTP INT64 type. +@param aElements The elements to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::AppendL(const RArray& aElements) + { + TUint count(aElements.Count()); + for (TUint i(0); (i < count); i++) + { + AppendInt64L(aElements[i]); + } + } + +/** +Appends the specified elements to the end of the MTP array. The array +element type MUST be of the MTP UINT64 type. +@param aElements The elements to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::AppendL(const RArray& aElements) + { + TUint count(aElements.Count()); + for (TUint i(0); (i < count); i++) + { + AppendUint64L(aElements[i]); + } + } + +/** +Appends the specified element to the end of the MTP array. The array +element type MUST be one of the MTP INT8, INT16, or INT32 types. +@param aElement The element to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::AppendIntL(TInt aElement) + { + __ASSERT_ALWAYS(((iElementType == EMTPTypeINT8) || (iElementType == EMTPTypeINT16) || (iElementType == EMTPTypeINT32)), Panic(EMTPTypeIdMismatch)); + // Relies on Symbian OS little-endianess. + AppendL(&aElement); + } + +/** +Appends the specified element to the end of the MTP array. The array +element type MUST be one of the MTP UINT8, UINT16, or UINT32 types. +@param aElement The element to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::AppendUintL(TUint aElement) + { + __ASSERT_ALWAYS(((iElementType == EMTPTypeUINT8) || (iElementType == EMTPTypeUINT16) || (iElementType == EMTPTypeUINT32)), Panic(EMTPTypeIdMismatch)); + // Relies on Symbian OS little-endianess. + AppendL(&aElement); + } + +/** +Appends the specified element to the end of the MTP array. The array +element type MUST be of the MTP INT64 type. +@param aElement The element to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::AppendInt64L(TInt64 aElement) + { + __ASSERT_ALWAYS((iElementType == EMTPTypeINT64) ,Panic(EMTPTypeIdMismatch)); + AppendL(&aElement); + } + +/** +Appends the specified element to the end of the MTP array. The array +element type MUST be of the MTP UINT64 type. +@param aElement The element to be appended to the MTP array. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::AppendUint64L(TUint64 aElement) + { + __ASSERT_ALWAYS((iElementType == EMTPTypeUINT64) ,Panic(EMTPTypeIdMismatch)); + AppendL(&aElement); + } + +/** +Provides a copy of the MTP element at the specified array index. +@param aIndex The index in the MTP array of the required element. +@param aElement On completion, a copy of the required element. +@leave One of the system wide error codes, if a processing failure occurs. +@panic MTPDataTypes 2, if aIndex is greater than or equal to the number of +objects currently contained in the array. +@panic MTPDataTypes 3, if aElement does not match the MTP type of the elements +contained in the array. +@panic MTPDataTypes 4, if aElement's size does not match that of the elements +contained in the array. +*/ +EXPORT_C void CMTPTypeArray::ElementL(TUint aIndex, MMTPType& aElement) const + { + __ASSERT_ALWAYS((aIndex < NumElements()), Panic(EMTPTypeBoundsError)); + __ASSERT_ALWAYS((aElement.Type() == iElementType), Panic(EMTPTypeIdMismatch)); + __ASSERT_ALWAYS((aElement.Size() == iElementSize), Panic(EMTPTypeSizeMismatch)); + + TBool commit(aElement.CommitRequired()); + TBool complete(EFalse); + TPtr8 dest(NULL, 0); + TInt err(aElement.FirstWriteChunk(dest)); + TUint offset(Offset(aIndex)); + + while (((err == KMTPChunkSequenceCompletion) || (err == KErrNone)) && (!complete)) + { + dest.Copy(&iBuffer[offset], dest.MaxLength()); + offset += dest.MaxLength(); + + if (commit) + { + aElement.CommitChunkL(dest); + } + + complete = (err == KMTPChunkSequenceCompletion); + if (!complete) + { + err = aElement.NextWriteChunk(dest); + } + } + + if (err != KMTPChunkSequenceCompletion) + { + User::Leave(err); + } + } + +/** +Provides a copy of the MTP element at the specified array index. The array +element type MUST be one of the MTP INT8, INT16, or INT32 types. +@param aIndex The index in the MTP array of the required element. +@panic MTPDataTypes 2, if aIndex is greater than or equal to the number of +objects currently contained in the array. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +@return aElement On completion, a copy of the required element. +*/ +EXPORT_C TInt CMTPTypeArray::ElementInt(TUint aIndex) const + { + __ASSERT_ALWAYS(((iElementType == EMTPTypeINT8) || (iElementType == EMTPTypeINT16) || (iElementType == EMTPTypeINT32)), Panic(EMTPTypeIdMismatch)); + // Relies on Symbian OS little-endianess. + TInt ret(0); + Element(aIndex, &ret); + return ret; + } + +/** +Provides a copy of the MTP element at the specified array index. The array +element type MUST be one of the MTP UINT8, UINT16, or UINT32 types. +@param aIndex The index in the MTP array of the required element. +@panic MTPDataTypes 2, if aIndex is greater than or equal to the number of +objects currently contained in the array. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +@return aElement On completion, a copy of the required element. +*/ +EXPORT_C TUint CMTPTypeArray::ElementUint(TUint aIndex) const + { + __ASSERT_ALWAYS(((iElementType == EMTPTypeUINT8) || (iElementType == EMTPTypeUINT16) || (iElementType == EMTPTypeUINT32)), Panic(EMTPTypeIdMismatch)); + // Relies on Symbian OS little-endianess. + TUint ret(0); + Element(aIndex, &ret); + return ret; + } + +/** +Provides a copy of the MTP element at the specified array index. The array +element type MUST be of the MTP INT64 type. +@param aIndex The index in the MTP array of the required element. +@panic MTPDataTypes 2, if aIndex is greater than or equal to the number of +objects currently contained in the array. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +@return aElement On completion, a copy of the required element. +*/ +EXPORT_C TInt64 CMTPTypeArray::ElementInt64(TUint aIndex) const + { + __ASSERT_ALWAYS((iElementType == EMTPTypeINT64) ,Panic(EMTPTypeIdMismatch)); + TInt64 ret(0); + Element(aIndex, &ret); + return ret; + } + +/** +Provides a copy of the MTP element at the specified array index. The array +element type MUST be of the MTP UINT64 type. +@param aIndex The index in the MTP array of the required element. +@panic MTPDataTypes 2, if aIndex is greater than or equal to the number of +objects currently contained in the array. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +@return aElement On completion, a copy of the required element. +*/ +EXPORT_C TUint64 CMTPTypeArray::ElementUint64(TUint aIndex) const + { + __ASSERT_ALWAYS((iElementType == EMTPTypeUINT64) ,Panic(EMTPTypeIdMismatch)); + TUint64 ret(0); + Element(aIndex, &ret); + return ret; + } + +/** +Provides a copy of the MTP array's element content. The array element type MUST +be one of the MTP INT8, INT16, or INT32 types. +@param aElements On completion, a copy of the MTP array's element content. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::Array(RArray& aElements) const + { + // Clear the array + aElements.Close(); + + TUint numElements(NumElements()); + for (TUint i(0); (i < numElements); i++) + { + aElements.Append(ElementInt(i)); + } + } + +/** +Provides a copy of the MTP array's element content. The array element type MUST +be one of the MTP UINT8, UINT16, or UINT32 types. +@param aElements On completion, a copy of the MTP array's element content. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::Array(RArray& aElements) const + { + // Clear the array + aElements.Close(); + + TUint numElements(NumElements()); + for (TUint i(0); (i < numElements); i++) + { + aElements.Append(ElementUint(i)); + } + } + +/** +Provides a copy of the MTP array's element content. The array element type MUST +be of the MTP INT64 type. +@param aElements On completion, a copy of the MTP array's element content. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::Array(RArray& aElements) const + { + // Clear the array + aElements.Close(); + + TUint numElements(NumElements()); + for (TUint i(0); (i < numElements); i++) + { + aElements.Append(ElementInt64(i)); + } + } + +/** +Provides a copy of the MTP array's element content. The array element type MUST +be of the MTP UINT64 type. +@param aElements On completion, a copy of the MTP array's element content. +@panic MTPDataTypes 3, if aElement does not match the MTP array's element type. +*/ +EXPORT_C void CMTPTypeArray::Array(RArray& aElements) const + { + // Clear the array + aElements.Close(); + + TUint numElements(NumElements()); + for (TUint i(0); (i < numElements); i++) + { + aElements.Append(ElementUint64(i)); + } + } + +EXPORT_C void CMTPTypeArray::ToDes( TDes8& aRetDes ) const + { + TInt retSize = aRetDes.MaxSize(); + if( 0 == retSize ) + { + return ; + } + + TInt length = NumElements() * iElementSize ; + if(retSize < length) + length = retSize; + + TPtrC8 ptrL = iBuffer.Left( length + KMTPNumElementsLen ); + TPtrC8 ptr = ptrL.Right(length); + aRetDes.Copy(ptr); + } + + +EXPORT_C void CMTPTypeArray::SetByDesL( const TDesC8& aDesc ) + { + TUint32 num = (aDesc.Length() / iElementSize); + SetNumElements( num ); + if ( num > 0 ) + { + ReAllocBufferL( num ); + memcpy(&iBuffer[KMTPFirstElementOffset], aDesc.Ptr(), aDesc.Length()); + } + } + +EXPORT_C TInt CMTPTypeArray::FirstReadChunk(TPtrC8& aChunk) const + { + aChunk.Set(&iBuffer[KMTPNumElementsOffset], Size()); + return KMTPChunkSequenceCompletion; + } + +EXPORT_C TInt CMTPTypeArray::NextReadChunk(TPtrC8& aChunk) const + { + aChunk.Set(NULL, 0); + return KErrNotReady; + } + +EXPORT_C TInt CMTPTypeArray::FirstWriteChunk(TPtr8& aChunk) + { + TInt ret(KErrNone); + aChunk.Set(&iBuffer[KMTPNumElementsOffset], 0, KMTPNumElementsLen); + iWriteSequenceState = ENumElements; + return ret; + } + +EXPORT_C TInt CMTPTypeArray::NextWriteChunk(TPtr8& aChunk) + { + TInt ret(KMTPChunkSequenceCompletion); + + if (iWriteSequenceState != ENumElements) + { + ret = KErrNotReady; + } + else + { + const TUint capacity(iBuffer.MaxLength() - KMTPNumElementsLen); + if (capacity > 0) + { + aChunk.Set(&iBuffer[KMTPFirstElementOffset], 0, capacity); + } + else + { + aChunk.Set(NULL, 0, 0); + } + + iWriteSequenceState = EElements; + } + + return ret; + } + +EXPORT_C TUint64 CMTPTypeArray::Size() const + { + return (KMTPNumElementsLen + (NumElements() * iElementSize)); + } + +EXPORT_C TUint CMTPTypeArray::Type() const + { + return iArrayType; + } + +EXPORT_C TBool CMTPTypeArray::CommitRequired() const + { + return ETrue; + } + +EXPORT_C MMTPType* CMTPTypeArray::CommitChunkL(TPtr8& aChunk) + { + switch (iWriteSequenceState) + { + case ENumElements: + /* + The first chunk specifies the NumElements field, and is used to re-size + the array buffer. + */ + ReAllocBufferL(NumElements()); + break; + + case EElements: + // Check that the correct number of array elements has been received. + { + TUint count(aChunk.Length() / iElementSize); + if (count != NumElements()) + { + SetInvalidL(); + } + iWriteSequenceState = EIdle; + } + break; + + case EIdle: + default: + User::Leave(KErrNotReady); + break; + } + return NULL; + } + +EXPORT_C TInt CMTPTypeArray::Validate() const + { + return iValidationState; + } + +CMTPTypeArray::CMTPTypeArray(TInt aArrayType, TInt aElementType, TUint aElementSize) : + iArrayType(aArrayType), + iElementSize(aElementSize), + iElementType(aElementType) + { + + } + +void CMTPTypeArray::ConstructL(TUint32 aNumElements) + { + ReAllocBufferL(aNumElements); + SetNumElements(0); + } + +void CMTPTypeArray::ConstructL(const RPointerArray& aElements) + { + TUint count(aElements.Count()); + ConstructL(count); + + for (TUint i(0); (i < count); i++) + { + AppendL(aElements[i]); + } + } + +void CMTPTypeArray::AppendL(const TAny* aElement) + { + const TUint index(NumElements()); + TUint32 numElements(index + 1); + + if (iBuffer.MaxLength() < BufferSize(numElements)) + { + ReAllocBufferL(numElements); + } + + memcpy(&iBuffer[Offset(index)], aElement, iElementSize); + SetNumElements(numElements); + } + +void CMTPTypeArray::Element(TUint aIndex, TAny* aElement) const + { + __ASSERT_ALWAYS((aIndex < NumElements()), Panic(EMTPTypeBoundsError)); + memcpy(aElement, &iBuffer[Offset(aIndex)], iElementSize); + } + +void CMTPTypeArray::ReAllocBufferL(TUint32 aNumElements) + { + TInt currentSize(iBuffer.MaxLength()); + TUint64 newSize(BufferSize(aNumElements)); + + if (newSize != currentSize) + { + if (newSize > KMaxTInt) + { + SetInvalidL(); + } + else + { + if (newSize < currentSize) + { + // Buffer is shrinking. + iBuffer.Close(); + } + iBuffer.ReAllocL(newSize); + iBuffer.SetMax(); + SetNumElements(aNumElements); + } + } + } + +void CMTPTypeArray::SetNumElements(TUint32 aNumElements) + { + memcpy(&iBuffer[KMTPNumElementsOffset], &aNumElements, KMTPNumElementsLen); + } + +TUint64 CMTPTypeArray::BufferSize(TUint32 aNumElements) const + { + return ((iElementSize * aNumElements) + KMTPNumElementsLen); + } + +TUint CMTPTypeArray::Offset(TUint aIndex) const + { + return (KMTPFirstElementOffset + (aIndex * iElementSize)); + } + +void CMTPTypeArray::SetInvalidL() + { + iValidationState = KMTPDataTypeInvalid; + User::Leave(iValidationState); + } + +void CMTPTypeArray::SimpleArrayTypeMetaDataL(TInt aArrayType, TInt& aElementType, TUint& aElementSize) + { + switch (aArrayType) + { + case EMTPTypeAINT8: + aElementType = EMTPTypeINT8; + aElementSize = KMTPTypeINT8Size; + break; + + case EMTPTypeAUINT8: + aElementType = EMTPTypeUINT8; + aElementSize = KMTPTypeUINT8Size; + break; + + case EMTPTypeAINT16: + aElementType = EMTPTypeINT16; + aElementSize = KMTPTypeINT16Size; + break; + + case EMTPTypeAUINT16: + aElementType = EMTPTypeUINT16; + aElementSize = KMTPTypeUINT16Size; + break; + + case EMTPTypeAINT32: + aElementType = EMTPTypeINT32; + aElementSize = KMTPTypeINT32Size; + break; + + case EMTPTypeAUINT32: + aElementType = EMTPTypeUINT32; + aElementSize = KMTPTypeUINT32Size; + break; + + case EMTPTypeAINT64: + aElementType = EMTPTypeINT64; + aElementSize = KMTPTypeINT64Size; + break; + + case EMTPTypeAUINT64: + aElementType = EMTPTypeUINT64; + aElementSize = KMTPTypeUINT64Size; + break; + + case EMTPTypeAINT128: + aElementType = EMTPTypeINT128; + aElementSize = KMTPTypeINT128Size; + break; + + case EMTPTypeAUINT128: + aElementType = EMTPTypeUINT128; + aElementSize = KMTPTypeUINT128Size; + break; + + default: + User::Leave(KErrArgument); + } + }