mtpfws/mtpfw/datatypes/src/cmtptypearray.cpp
changeset 0 d0791faffa3f
--- /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);
+        } 
+    }