--- /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 <mtp/cmtptypearray.h>
+#include <mtp/mtpdatatypeconstants.h>
+#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<TInt>& 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<TUint>& 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<TInt64>& 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<TUint64>& 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<TInt>& 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<TUint>& 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<TInt64>& 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<TUint64>& 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<const TUint32*>(&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<TInt>& 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<TUint>& 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<TInt64>& 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<TUint64>& 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<TInt>& 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<TUint>& 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<TInt64>& 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<TUint64>& 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<MMTPType>& 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);
+ }
+ }