mtpfws/mtpfw/datatypes/src/cmtptypearray.cpp
changeset 0 d0791faffa3f
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @publishedPartner
       
    19 */
       
    20 
       
    21 #include <mtp/cmtptypearray.h>
       
    22 #include <mtp/mtpdatatypeconstants.h>
       
    23 #include "mtpdatatypespanic.h"
       
    24 
       
    25 // Array type constants.
       
    26 const TUint KMTPNumElementsLen(sizeof(TUint32));
       
    27 const TUint KMTPNumElementsOffset(0);
       
    28 const TUint KMTPFirstElementOffset(KMTPNumElementsLen);
       
    29 const TUint KMTPGranularity(8);
       
    30 
       
    31 /**
       
    32 MTP array data type factory method. This method is used to create an empty MTP
       
    33 array.
       
    34 @param aElementType The MTP type identifier of the elements contained in the 
       
    35 array.
       
    36 @param aElementSize The size (in bytes) of the elements contained in the array.
       
    37 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
    38 @leave One of the system wide error codes, if a processing failure occurs.
       
    39 */   
       
    40 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aElementType, TUint aElementSize)
       
    41     {
       
    42     return NewL(EMTPTypeArray, aElementType, aElementSize);
       
    43     }
       
    44 
       
    45 /**
       
    46 MTP array data type factory method. This method is used to create an empty MTP
       
    47 array. A pointer to the MTP array data type is placed on the cleanup stack.
       
    48 @param aElementType The MTP type identifier of the elements contained in the 
       
    49 array.
       
    50 @param aElementSize The size (in bytes) of the elements which contained in 
       
    51 array.
       
    52 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
    53 @leave One of the system wide error codes, if a processing failure occurs.
       
    54 */  
       
    55 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aElementType, TUint aElementSize)
       
    56     {
       
    57     return CMTPTypeArray::NewLC(EMTPTypeArray, aElementType, aElementSize);
       
    58     }
       
    59 
       
    60 /**
       
    61 MTP array data type factory method. This method is used to create an empty MTP
       
    62 array of the specified MTP array type.
       
    63 @param aArrayType The MTP type identifier to be assigned to the array.
       
    64 @param aElementType The MTP type identifier of the elements contained in the 
       
    65 array.
       
    66 @param aElementSize The size (in bytes) of the elements contained in the array.
       
    67 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
    68 @leave One of the system wide error codes, if a processing failure occurs.
       
    69 */   
       
    70 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aArrayType, TInt aElementType, TUint aElementSize)
       
    71     {
       
    72     CMTPTypeArray* self = NewLC(aArrayType, aElementType, aElementSize);
       
    73     CleanupStack::Pop(self);
       
    74     return self;
       
    75     }
       
    76 
       
    77 /**
       
    78 MTP array data type factory method. This method is used to create an empty MTP
       
    79 array of the specified MTP array type. A pointer to the MTP array data type is 
       
    80 placed on the cleanup stack.
       
    81 @param aArrayType The MTP type identifier to be assigned to the array.
       
    82 @param aElementType The MTP type identifier of the elements contained in the 
       
    83 array.
       
    84 @param aElementSize The size (in bytes) of the elements which contained in 
       
    85 array.
       
    86 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
    87 @leave One of the system wide error codes, if a processing failure occurs.
       
    88 */  
       
    89 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aArrayType, TInt aElementType, TUint aElementSize)
       
    90     {
       
    91     CMTPTypeArray* self = new(ELeave) CMTPTypeArray(aArrayType, aElementType, aElementSize);
       
    92     CleanupStack::PushL(self);
       
    93     self->ConstructL(KMTPGranularity);
       
    94     return self;
       
    95     }
       
    96     
       
    97 /**
       
    98 MTP simple data type array factory method. This method is used to create
       
    99 an empty MTP array of the specified MTP simple data type.
       
   100 @param aArrayType The array data type indentifier datacode. This must be in 
       
   101 the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   102 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   103 @leave KErrArgument, if aArrayType is not in the range 
       
   104 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   105 @leave One of the system wide error codes, if a processing failure occurs.
       
   106 */ 
       
   107 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aArrayType)
       
   108     {
       
   109     CMTPTypeArray* self = NewLC(aArrayType);
       
   110     CleanupStack::Pop(self);
       
   111     return self;   
       
   112     } 
       
   113 
       
   114 /**
       
   115 MTP simple data type array factory method. This method is used to create
       
   116 an MTP array of the specified MTP simple data type with the specified element 
       
   117 content.
       
   118 @param aArrayType The array data type indentifier datacode. This must be in 
       
   119 the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   120 @param aElements The initial set of element values.
       
   121 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   122 @leave KErrArgument, if aArrayType is not in the range 
       
   123 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   124 @leave One of the system wide error codes, if a processing failure occurs.
       
   125 */ 
       
   126 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aArrayType, const RArray<TInt>& aElements)
       
   127     {
       
   128     CMTPTypeArray* self = NewLC(aArrayType, aElements);
       
   129     CleanupStack::Pop(self);
       
   130     return self; 
       
   131     }
       
   132 
       
   133 /**
       
   134 MTP simple data type array factory method. This method is used to create
       
   135 an MTP array of the specified MTP simple data type with the specified element 
       
   136 content.
       
   137 @param aArrayType The array data type indentifier datacode. This must be in 
       
   138 the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   139 @param aElements The initial set of element values.
       
   140 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   141 @leave KErrArgument, if aArrayType is not in the range 
       
   142 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   143 @leave One of the system wide error codes, if a processing failure occurs.
       
   144 */ 
       
   145 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(TInt aArrayType, const RArray<TUint>& aElements)
       
   146     {
       
   147     CMTPTypeArray* self = NewLC(aArrayType, aElements);
       
   148     CleanupStack::Pop(self);
       
   149     return self; 
       
   150     }
       
   151 
       
   152 /**
       
   153 MTP AINT64 array factory method. This method is used to create an MTP AINT64 
       
   154 array with the specified element content.
       
   155 @param aElements The initial set of element values.
       
   156 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   157 @leave KErrArgument, if aArrayType is not in the range 
       
   158 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   159 @leave One of the system wide error codes, if a processing failure occurs.
       
   160 */ 
       
   161 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(const RArray<TInt64>& aElements)
       
   162     {
       
   163     CMTPTypeArray* self = NewLC(aElements);
       
   164     CleanupStack::Pop(self); 
       
   165     return self; 
       
   166     }
       
   167 
       
   168 /**
       
   169 MTP AUINT64 array factory method. This method is used to create an MTP AINT64 
       
   170 array with the specified element content.
       
   171 @param aElements The initial set of element values.
       
   172 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   173 @leave KErrArgument, if aArrayType is not in the range 
       
   174 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   175 @leave One of the system wide error codes, if a processing failure occurs.
       
   176 */ 
       
   177 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewL(const RArray<TUint64>& aElements)
       
   178     {
       
   179     CMTPTypeArray* self = NewLC(aElements);
       
   180     CleanupStack::Pop(self);
       
   181     return self; 
       
   182     }
       
   183     
       
   184 /**
       
   185 MTP simple data type array factory method. This method is used to create
       
   186 an empty MTP array of the specified MTP simple data type. A pointer to the MTP 
       
   187 array data type is placed on the cleanup stack.
       
   188 @param aArrayType The array data type indentifier datacode. This must be in 
       
   189 the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   190 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   191 @leave KErrArgument, if aArrayType is not in the range 
       
   192 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   193 @leave One of the system wide error codes, if a processing failure occurs.
       
   194 */ 
       
   195 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aArrayType)
       
   196     {
       
   197     TInt    type(aArrayType);
       
   198     TUint   size(0);
       
   199     SimpleArrayTypeMetaDataL(aArrayType, type, size);
       
   200     CMTPTypeArray* self = new(ELeave) CMTPTypeArray(aArrayType, type, size);
       
   201     CleanupStack::PushL(self);
       
   202     self->ConstructL(KMTPGranularity);
       
   203     return self;   
       
   204     }
       
   205 
       
   206 /**
       
   207 MTP simple data type array factory method. This method is used to create
       
   208 an MTP array of the specified MTP simple data type with the specified element 
       
   209 content. A pointer to the MTP array data type is placed on the cleanup stack.
       
   210 @param aArrayType The array data type indentifier datacode. This must be in 
       
   211 the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   212 @param aElements The initial set of element values.
       
   213 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   214 @leave KErrArgument, if aArrayType is not in the range 
       
   215 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   216 @leave One of the system wide error codes, if a processing failure occurs.
       
   217 */ 
       
   218 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aArrayType, const RArray<TInt>& aElements)
       
   219     {
       
   220     TInt    type(aArrayType);
       
   221     TUint   size(0);
       
   222     SimpleArrayTypeMetaDataL(aArrayType, type, size);
       
   223     CMTPTypeArray* self = new(ELeave) CMTPTypeArray(aArrayType, type, size);
       
   224     CleanupStack::PushL(self);
       
   225     
       
   226     TUint count(aElements.Count());
       
   227     self->ConstructL(count);
       
   228     
       
   229     for (TUint i(0); (i < count); i++)
       
   230         {
       
   231         self->AppendIntL(aElements[i]);
       
   232         }
       
   233     
       
   234     return self; 
       
   235     }
       
   236 
       
   237 /**
       
   238 MTP simple data type array factory method. This method is used to create
       
   239 an MTP array of the specified MTP simple data type with the specified element 
       
   240 content. A pointer to the MTP array data type is placed on the cleanup stack.
       
   241 @param aArrayType The array data type indentifier datacode. This must be in 
       
   242 the range EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   243 @param aElements The initial set of element values.
       
   244 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   245 @leave KErrArgument, if aArrayType is not in the range 
       
   246 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   247 @leave One of the system wide error codes, if a processing failure occurs.
       
   248 */ 
       
   249 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(TInt aArrayType, const RArray<TUint>& aElements)
       
   250     {
       
   251     TInt    type(aArrayType);
       
   252     TUint   size(0);
       
   253     SimpleArrayTypeMetaDataL(aArrayType, type, size);
       
   254     CMTPTypeArray* self = new(ELeave) CMTPTypeArray(aArrayType, type, size);
       
   255     CleanupStack::PushL(self);
       
   256     
       
   257     TUint count(aElements.Count());
       
   258     self->ConstructL(count);
       
   259     
       
   260     for (TUint i(0); (i < count); i++)
       
   261         {
       
   262         self->AppendUintL(aElements[i]);
       
   263         }
       
   264     
       
   265     return self; 
       
   266     }
       
   267 
       
   268 /**
       
   269 MTP AINT64 array factory method. This method is used to create an MTP AINT64 
       
   270 array with the specified element content. A pointer to the MTP array data type 
       
   271 is placed on the cleanup stack.
       
   272 @param aElements The initial set of element values.
       
   273 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   274 @leave KErrArgument, if aArrayType is not in the range 
       
   275 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   276 @leave One of the system wide error codes, if a processing failure occurs.
       
   277 */ 
       
   278 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(const RArray<TInt64>& aElements)
       
   279     {
       
   280     TInt    type(EMTPTypeINT64);
       
   281     TUint   size(0);
       
   282     SimpleArrayTypeMetaDataL(EMTPTypeAINT64, type, size);
       
   283     CMTPTypeArray* self = new(ELeave) CMTPTypeArray(EMTPTypeAINT64, type, size);
       
   284     CleanupStack::PushL(self);
       
   285     
       
   286     TUint count(aElements.Count());
       
   287     self->ConstructL(count);
       
   288     
       
   289     for (TUint i(0); (i < count); i++)
       
   290         {
       
   291         self->AppendInt64L(aElements[i]);
       
   292         }
       
   293     
       
   294     return self; 
       
   295     }
       
   296 
       
   297 /**
       
   298 MTP AUINT64 array factory method. This method is used to create an MTP AUINT64 
       
   299 array with the specified element content. A pointer to the MTP array data type 
       
   300 is placed on the cleanup stack.
       
   301 @param aElements The initial set of element values.
       
   302 @return A pointer to an empty MTP array data type. Ownership IS transfered.
       
   303 @leave KErrArgument, if aArrayType is not in the range 
       
   304 EMTPTypeFirstSimpleArrayType ... EMTPTypeLastSimpleArrayType.
       
   305 @leave One of the system wide error codes, if a processing failure occurs.
       
   306 */ 
       
   307 EXPORT_C CMTPTypeArray* CMTPTypeArray::NewLC(const RArray<TUint64>& aElements)
       
   308     {
       
   309     TInt    type(EMTPTypeUINT64);
       
   310     TUint   size(0);
       
   311     SimpleArrayTypeMetaDataL(EMTPTypeAUINT64, type, size);
       
   312     CMTPTypeArray* self = new(ELeave) CMTPTypeArray(EMTPTypeAUINT64, type, size);
       
   313     CleanupStack::PushL(self);
       
   314     
       
   315     TUint count(aElements.Count());
       
   316     self->ConstructL(count);
       
   317     
       
   318     for (TUint i(0); (i < count); i++)
       
   319         {
       
   320         self->AppendUint64L(aElements[i]);
       
   321         }
       
   322     
       
   323     return self; 
       
   324     }
       
   325 
       
   326 /**
       
   327 Destructor
       
   328 */
       
   329 EXPORT_C CMTPTypeArray::~CMTPTypeArray()
       
   330     {
       
   331     iBuffer.Close();    
       
   332     }
       
   333     
       
   334 /**
       
   335 Provides the MTP identifier of the elements contained in the array.
       
   336 @return The MTP identifier of the elements contained in the array.
       
   337 */ 
       
   338 EXPORT_C TInt CMTPTypeArray::ElementType() const
       
   339     {
       
   340     return iElementType;    
       
   341     }
       
   342     
       
   343 /**
       
   344 Provides the number of elements contained in the MTP array.
       
   345 @return The number of elements contained in the MTP array.
       
   346 */ 
       
   347 EXPORT_C TUint32 CMTPTypeArray::NumElements() const
       
   348     {
       
   349     return *(reinterpret_cast<const TUint32*>(&iBuffer[KMTPNumElementsOffset]));
       
   350     }
       
   351 
       
   352 /**
       
   353 Appends the specified element to the end of the MTP array.
       
   354 @param aElement The element to be appended to the MTP array.
       
   355 @leave One of the system wide error codes, if a processing failure occurs.
       
   356 @panic MTPDataTypes 3, if aElement does not match the MTP type of the elements
       
   357 contained in the array.
       
   358 */
       
   359 EXPORT_C void CMTPTypeArray::AppendL(const MMTPType& aElement)
       
   360     {    
       
   361     __ASSERT_ALWAYS((aElement.Type() == iElementType), Panic(EMTPTypeIdMismatch));
       
   362     const TUint index(NumElements());
       
   363     TUint32 numElements(index + 1);
       
   364     
       
   365     if (iBuffer.MaxLength() < BufferSize(numElements))
       
   366         {
       
   367         ReAllocBufferL(numElements);
       
   368         }
       
   369         
       
   370     TBool complete(EFalse);
       
   371     TUint offset(Offset(index));
       
   372     TPtrC8 src;
       
   373     const TUint startOffset(offset);
       
   374     
       
   375     TInt err(aElement.FirstReadChunk(src));
       
   376     while (((err == KMTPChunkSequenceCompletion) || (err == KErrNone)) && (!complete))
       
   377         {
       
   378         __ASSERT_ALWAYS(((offset - startOffset) <= iElementSize), Panic(EMTPTypeSizeMismatch));
       
   379         memcpy(&iBuffer[offset], src.Ptr(), src.Length());
       
   380         offset += src.Length();
       
   381         
       
   382         complete = (err == KMTPChunkSequenceCompletion);
       
   383         if (!complete)
       
   384             {
       
   385             err = aElement.NextReadChunk(src);                
       
   386             } 
       
   387         }
       
   388         
       
   389     if (err != KMTPChunkSequenceCompletion)
       
   390         {
       
   391         User::Leave(err);            
       
   392         }
       
   393         
       
   394     SetNumElements(numElements);
       
   395     }
       
   396 
       
   397 /**
       
   398 Appends the specified elements to the end of the MTP array. The array 
       
   399 element type MUST be one of the MTP INT8, INT16, or INT32 types.
       
   400 @param aElements The elements to be appended to the MTP array.
       
   401 @leave One of the system wide error codes, if a processing failure occurs.
       
   402 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   403 */   
       
   404 EXPORT_C void CMTPTypeArray::AppendL(const RArray<TInt>& aElements)
       
   405     {
       
   406     TUint count(aElements.Count());
       
   407     for (TUint i(0); (i < count); i++)
       
   408         {
       
   409         AppendIntL(aElements[i]);
       
   410         }
       
   411     }
       
   412 
       
   413 /**
       
   414 Appends the specified elements to the end of the MTP array. The array 
       
   415 element type MUST be one of the MTP UINT8, UINT16, or UINT32 types.
       
   416 @param aElements The elements to be appended to the MTP array.
       
   417 @leave One of the system wide error codes, if a processing failure occurs.
       
   418 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   419 */    
       
   420 EXPORT_C void CMTPTypeArray::AppendL(const RArray<TUint>& aElements)
       
   421     {
       
   422     TUint count(aElements.Count());
       
   423     for (TUint i(0); (i < count); i++)
       
   424         {
       
   425         AppendUintL(aElements[i]);
       
   426         }
       
   427     }
       
   428 
       
   429 /**
       
   430 Appends the specified elements to the end of the MTP array. The array 
       
   431 element type MUST be of the MTP INT64 type.
       
   432 @param aElements The elements to be appended to the MTP array.
       
   433 @leave One of the system wide error codes, if a processing failure occurs.
       
   434 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   435 */   
       
   436 EXPORT_C void CMTPTypeArray::AppendL(const RArray<TInt64>& aElements)
       
   437     {
       
   438     TUint count(aElements.Count());
       
   439     for (TUint i(0); (i < count); i++)
       
   440         {
       
   441         AppendInt64L(aElements[i]);
       
   442         }
       
   443     }
       
   444 
       
   445 /**
       
   446 Appends the specified elements to the end of the MTP array. The array 
       
   447 element type MUST be of the MTP UINT64 type.
       
   448 @param aElements The elements to be appended to the MTP array.
       
   449 @leave One of the system wide error codes, if a processing failure occurs.
       
   450 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   451 */
       
   452 EXPORT_C void CMTPTypeArray::AppendL(const RArray<TUint64>& aElements)
       
   453     {
       
   454     TUint count(aElements.Count());
       
   455     for (TUint i(0); (i < count); i++)
       
   456         {
       
   457         AppendUint64L(aElements[i]);
       
   458         }
       
   459     }
       
   460 
       
   461 /**
       
   462 Appends the specified element to the end of the MTP array. The array 
       
   463 element type MUST be one of the MTP INT8, INT16, or INT32 types.
       
   464 @param aElement The element to be appended to the MTP array.
       
   465 @leave One of the system wide error codes, if a processing failure occurs.
       
   466 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   467 */
       
   468 EXPORT_C void CMTPTypeArray::AppendIntL(TInt aElement)
       
   469     {
       
   470     __ASSERT_ALWAYS(((iElementType == EMTPTypeINT8) || (iElementType == EMTPTypeINT16) || (iElementType == EMTPTypeINT32)), Panic(EMTPTypeIdMismatch));
       
   471     // Relies on Symbian OS little-endianess.
       
   472     AppendL(&aElement);
       
   473     }
       
   474 
       
   475 /**
       
   476 Appends the specified element to the end of the MTP array. The array 
       
   477 element type MUST be one of the MTP UINT8, UINT16, or UINT32 types.
       
   478 @param aElement The element to be appended to the MTP array.
       
   479 @leave One of the system wide error codes, if a processing failure occurs.
       
   480 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   481 */
       
   482 EXPORT_C void CMTPTypeArray::AppendUintL(TUint aElement)
       
   483     {  
       
   484     __ASSERT_ALWAYS(((iElementType == EMTPTypeUINT8) || (iElementType == EMTPTypeUINT16) || (iElementType == EMTPTypeUINT32)), Panic(EMTPTypeIdMismatch));
       
   485     // Relies on Symbian OS little-endianess.
       
   486     AppendL(&aElement);  
       
   487     }
       
   488 
       
   489 /**
       
   490 Appends the specified element to the end of the MTP array. The array 
       
   491 element type MUST be of the MTP INT64 type.
       
   492 @param aElement The element to be appended to the MTP array.
       
   493 @leave One of the system wide error codes, if a processing failure occurs.
       
   494 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   495 */
       
   496 EXPORT_C void CMTPTypeArray::AppendInt64L(TInt64 aElement)
       
   497     {    
       
   498     __ASSERT_ALWAYS((iElementType == EMTPTypeINT64) ,Panic(EMTPTypeIdMismatch));
       
   499     AppendL(&aElement);
       
   500     }
       
   501 
       
   502 /**
       
   503 Appends the specified element to the end of the MTP array. The array 
       
   504 element type MUST be of the MTP UINT64 type.
       
   505 @param aElement The element to be appended to the MTP array.
       
   506 @leave One of the system wide error codes, if a processing failure occurs.
       
   507 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   508 */
       
   509 EXPORT_C void CMTPTypeArray::AppendUint64L(TUint64 aElement)
       
   510     {    
       
   511     __ASSERT_ALWAYS((iElementType == EMTPTypeUINT64) ,Panic(EMTPTypeIdMismatch));
       
   512     AppendL(&aElement);
       
   513     }
       
   514 
       
   515 /**
       
   516 Provides a copy of the MTP element at the specified array index.
       
   517 @param aIndex The index in the MTP array of the required element.
       
   518 @param aElement On completion, a copy of the required element.
       
   519 @leave One of the system wide error codes, if a processing failure occurs.
       
   520 @panic MTPDataTypes 2, if aIndex is greater than or equal to the number of 
       
   521 objects currently contained in the array.
       
   522 @panic MTPDataTypes 3, if aElement does not match the MTP type of the elements
       
   523 contained in the array.
       
   524 @panic MTPDataTypes 4, if aElement's size does not match that of the elements
       
   525 contained in the array.
       
   526 */
       
   527 EXPORT_C void CMTPTypeArray::ElementL(TUint aIndex, MMTPType& aElement) const
       
   528     {
       
   529     __ASSERT_ALWAYS((aIndex < NumElements()), Panic(EMTPTypeBoundsError));
       
   530     __ASSERT_ALWAYS((aElement.Type() == iElementType), Panic(EMTPTypeIdMismatch));
       
   531     __ASSERT_ALWAYS((aElement.Size() == iElementSize), Panic(EMTPTypeSizeMismatch));
       
   532     
       
   533     TBool commit(aElement.CommitRequired());
       
   534     TBool complete(EFalse);
       
   535     TPtr8 dest(NULL, 0);
       
   536     TInt err(aElement.FirstWriteChunk(dest));
       
   537     TUint offset(Offset(aIndex));
       
   538     
       
   539     while (((err == KMTPChunkSequenceCompletion) || (err == KErrNone)) && (!complete))
       
   540         {
       
   541         dest.Copy(&iBuffer[offset], dest.MaxLength());
       
   542         offset += dest.MaxLength();
       
   543         
       
   544         if (commit)
       
   545             {
       
   546             aElement.CommitChunkL(dest);
       
   547             }
       
   548         
       
   549         complete = (err == KMTPChunkSequenceCompletion);
       
   550         if (!complete)
       
   551             {
       
   552             err = aElement.NextWriteChunk(dest);
       
   553             }
       
   554         }
       
   555         
       
   556     if (err != KMTPChunkSequenceCompletion)
       
   557         {
       
   558         User::Leave(err);            
       
   559         }
       
   560     }
       
   561 
       
   562 /**
       
   563 Provides a copy of the MTP element at the specified array index. The array 
       
   564 element type MUST be one of the MTP INT8, INT16, or INT32 types.
       
   565 @param aIndex The index in the MTP array of the required element.
       
   566 @panic MTPDataTypes 2, if aIndex is greater than or equal to the number of 
       
   567 objects currently contained in the array.
       
   568 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   569 @return aElement On completion, a copy of the required element.
       
   570 */
       
   571 EXPORT_C TInt CMTPTypeArray::ElementInt(TUint aIndex) const
       
   572     {
       
   573     __ASSERT_ALWAYS(((iElementType == EMTPTypeINT8) || (iElementType == EMTPTypeINT16) || (iElementType == EMTPTypeINT32)), Panic(EMTPTypeIdMismatch));
       
   574     // Relies on Symbian OS little-endianess.
       
   575     TInt ret(0);
       
   576     Element(aIndex, &ret);
       
   577     return ret;
       
   578     }
       
   579 
       
   580 /**
       
   581 Provides a copy of the MTP element at the specified array index. The array 
       
   582 element type MUST be one of the MTP UINT8, UINT16, or UINT32 types.
       
   583 @param aIndex The index in the MTP array of the required element.
       
   584 @panic MTPDataTypes 2, if aIndex is greater than or equal to the number of 
       
   585 objects currently contained in the array.
       
   586 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   587 @return aElement On completion, a copy of the required element.
       
   588 */
       
   589 EXPORT_C TUint CMTPTypeArray::ElementUint(TUint aIndex) const
       
   590     {
       
   591     __ASSERT_ALWAYS(((iElementType == EMTPTypeUINT8) || (iElementType == EMTPTypeUINT16) || (iElementType == EMTPTypeUINT32)), Panic(EMTPTypeIdMismatch));
       
   592     // Relies on Symbian OS little-endianess.
       
   593     TUint ret(0);
       
   594     Element(aIndex, &ret);
       
   595     return ret;
       
   596     }
       
   597 
       
   598 /**
       
   599 Provides a copy of the MTP element at the specified array index. The array 
       
   600 element type MUST be of the MTP INT64 type.
       
   601 @param aIndex The index in the MTP array of the required element.
       
   602 @panic MTPDataTypes 2, if aIndex is greater than or equal to the number of 
       
   603 objects currently contained in the array.
       
   604 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   605 @return aElement On completion, a copy of the required element.
       
   606 */
       
   607 EXPORT_C TInt64 CMTPTypeArray::ElementInt64(TUint aIndex) const
       
   608     {
       
   609     __ASSERT_ALWAYS((iElementType == EMTPTypeINT64) ,Panic(EMTPTypeIdMismatch));
       
   610     TInt64 ret(0);
       
   611     Element(aIndex, &ret);
       
   612     return ret;
       
   613     }
       
   614 
       
   615 /**
       
   616 Provides a copy of the MTP element at the specified array index. The array 
       
   617 element type MUST be of the MTP UINT64 type.
       
   618 @param aIndex The index in the MTP array of the required element.
       
   619 @panic MTPDataTypes 2, if aIndex is greater than or equal to the number of 
       
   620 objects currently contained in the array.
       
   621 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   622 @return aElement On completion, a copy of the required element.
       
   623 */
       
   624 EXPORT_C TUint64 CMTPTypeArray::ElementUint64(TUint aIndex) const
       
   625     {
       
   626     __ASSERT_ALWAYS((iElementType == EMTPTypeUINT64) ,Panic(EMTPTypeIdMismatch));
       
   627     TUint64 ret(0);
       
   628     Element(aIndex, &ret);
       
   629     return ret;
       
   630     }
       
   631 
       
   632 /**
       
   633 Provides a copy of the MTP array's element content. The array element type MUST
       
   634 be one of the MTP INT8, INT16, or INT32 types.
       
   635 @param aElements On completion, a copy of the MTP array's element content.
       
   636 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   637 */
       
   638 EXPORT_C void CMTPTypeArray::Array(RArray<TInt>& aElements) const
       
   639     {
       
   640     // Clear the array    
       
   641     aElements.Close();
       
   642 
       
   643     TUint numElements(NumElements());
       
   644     for (TUint i(0); (i < numElements); i++)
       
   645         {
       
   646         aElements.Append(ElementInt(i));
       
   647         }
       
   648     }
       
   649 
       
   650 /**
       
   651 Provides a copy of the MTP array's element content. The array element type MUST
       
   652 be one of the MTP UINT8, UINT16, or UINT32 types.
       
   653 @param aElements On completion, a copy of the MTP array's element content.
       
   654 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   655 */
       
   656 EXPORT_C void CMTPTypeArray::Array(RArray<TUint>& aElements) const
       
   657     {
       
   658     // Clear the array    
       
   659     aElements.Close();
       
   660 
       
   661     TUint numElements(NumElements());
       
   662     for (TUint i(0); (i < numElements); i++)
       
   663         {
       
   664         aElements.Append(ElementUint(i));
       
   665         }
       
   666     }
       
   667 
       
   668 /**
       
   669 Provides a copy of the MTP array's element content. The array element type MUST
       
   670 be of the MTP INT64 type.
       
   671 @param aElements On completion, a copy of the MTP array's element content.
       
   672 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   673 */
       
   674 EXPORT_C void CMTPTypeArray::Array(RArray<TInt64>& aElements) const
       
   675     {
       
   676     // Clear the array    
       
   677     aElements.Close();
       
   678 
       
   679     TUint numElements(NumElements());
       
   680     for (TUint i(0); (i < numElements); i++)
       
   681         {
       
   682         aElements.Append(ElementInt64(i));
       
   683         }
       
   684     }
       
   685 
       
   686 /**
       
   687 Provides a copy of the MTP array's element content. The array element type MUST
       
   688 be of the MTP UINT64 type.
       
   689 @param aElements On completion, a copy of the MTP array's element content.
       
   690 @panic MTPDataTypes 3, if aElement does not match the MTP array's element type.
       
   691 */
       
   692 EXPORT_C void CMTPTypeArray::Array(RArray<TUint64>& aElements) const
       
   693     {
       
   694     // Clear the array    
       
   695     aElements.Close();
       
   696 
       
   697     TUint numElements(NumElements());
       
   698     for (TUint i(0); (i < numElements); i++)
       
   699         {
       
   700         aElements.Append(ElementUint64(i));
       
   701         }
       
   702     }
       
   703 
       
   704 EXPORT_C void CMTPTypeArray::ToDes( TDes8& aRetDes ) const
       
   705     {  
       
   706     TInt retSize = aRetDes.MaxSize();
       
   707     if( 0 == retSize )
       
   708        {
       
   709        return ;
       
   710        }
       
   711     
       
   712     TInt length = NumElements() * iElementSize ;
       
   713     if(retSize < length)
       
   714         length = retSize;
       
   715     
       
   716     TPtrC8 ptrL = iBuffer.Left( length + KMTPNumElementsLen );
       
   717     TPtrC8 ptr = ptrL.Right(length);
       
   718     aRetDes.Copy(ptr);
       
   719     }
       
   720 
       
   721 
       
   722 EXPORT_C void CMTPTypeArray::SetByDesL( const TDesC8& aDesc ) 
       
   723     {
       
   724     TUint32 num = (aDesc.Length() / iElementSize);
       
   725     SetNumElements( num );
       
   726     if ( num > 0 )
       
   727     	{
       
   728     	ReAllocBufferL( num );
       
   729     	memcpy(&iBuffer[KMTPFirstElementOffset], aDesc.Ptr(), aDesc.Length());
       
   730     	}
       
   731     }
       
   732 
       
   733 EXPORT_C TInt CMTPTypeArray::FirstReadChunk(TPtrC8& aChunk) const
       
   734     {
       
   735     aChunk.Set(&iBuffer[KMTPNumElementsOffset], Size());
       
   736     return KMTPChunkSequenceCompletion;
       
   737     }
       
   738 
       
   739 EXPORT_C TInt CMTPTypeArray::NextReadChunk(TPtrC8& aChunk) const
       
   740     {
       
   741     aChunk.Set(NULL, 0);
       
   742     return KErrNotReady;
       
   743     }
       
   744 
       
   745 EXPORT_C TInt CMTPTypeArray::FirstWriteChunk(TPtr8& aChunk)
       
   746     {    
       
   747     TInt ret(KErrNone);
       
   748     aChunk.Set(&iBuffer[KMTPNumElementsOffset], 0, KMTPNumElementsLen);
       
   749     iWriteSequenceState = ENumElements;
       
   750     return ret;
       
   751     }
       
   752 
       
   753 EXPORT_C TInt CMTPTypeArray::NextWriteChunk(TPtr8& aChunk)
       
   754     {
       
   755     TInt ret(KMTPChunkSequenceCompletion);
       
   756     
       
   757     if (iWriteSequenceState != ENumElements)
       
   758         {
       
   759         ret = KErrNotReady;
       
   760         }
       
   761     else
       
   762         {
       
   763         const TUint capacity(iBuffer.MaxLength() - KMTPNumElementsLen);
       
   764         if (capacity > 0)
       
   765             {
       
   766             aChunk.Set(&iBuffer[KMTPFirstElementOffset], 0, capacity);
       
   767             }
       
   768         else
       
   769             {
       
   770             aChunk.Set(NULL, 0, 0);
       
   771             }
       
   772             
       
   773         iWriteSequenceState = EElements;
       
   774         }
       
   775         
       
   776     return ret;
       
   777     }
       
   778 
       
   779 EXPORT_C TUint64 CMTPTypeArray::Size() const
       
   780     {
       
   781     return (KMTPNumElementsLen + (NumElements() * iElementSize));
       
   782     }
       
   783 
       
   784 EXPORT_C TUint CMTPTypeArray::Type() const
       
   785     {
       
   786     return iArrayType;
       
   787     }
       
   788 
       
   789 EXPORT_C TBool CMTPTypeArray::CommitRequired() const
       
   790     {
       
   791     return ETrue;
       
   792     }
       
   793 
       
   794 EXPORT_C MMTPType* CMTPTypeArray::CommitChunkL(TPtr8& aChunk)
       
   795     {
       
   796     switch (iWriteSequenceState)
       
   797         {
       
   798     case ENumElements:
       
   799         /* 
       
   800         The first chunk specifies the NumElements field, and is used to re-size 
       
   801         the array buffer.
       
   802         */
       
   803         ReAllocBufferL(NumElements());
       
   804         break;
       
   805         
       
   806     case EElements:
       
   807         // Check that the correct number of array elements has been received.
       
   808         {            
       
   809         TUint count(aChunk.Length() / iElementSize);
       
   810         if (count != NumElements())
       
   811             {
       
   812             SetInvalidL();
       
   813             }
       
   814         iWriteSequenceState = EIdle;
       
   815         }
       
   816         break;
       
   817         
       
   818     case EIdle:
       
   819     default:
       
   820         User::Leave(KErrNotReady);
       
   821         break;
       
   822         }
       
   823     return NULL;
       
   824     }
       
   825     
       
   826 EXPORT_C TInt CMTPTypeArray::Validate() const
       
   827     {
       
   828     return iValidationState;
       
   829     }
       
   830     
       
   831 CMTPTypeArray::CMTPTypeArray(TInt aArrayType, TInt aElementType, TUint aElementSize) :
       
   832     iArrayType(aArrayType),
       
   833     iElementSize(aElementSize),
       
   834     iElementType(aElementType)
       
   835     {
       
   836         
       
   837     }
       
   838     
       
   839 void CMTPTypeArray::ConstructL(TUint32 aNumElements)
       
   840     {
       
   841     ReAllocBufferL(aNumElements);
       
   842     SetNumElements(0);
       
   843     }
       
   844 
       
   845 void CMTPTypeArray::ConstructL(const RPointerArray<MMTPType>& aElements)
       
   846     {
       
   847     TUint count(aElements.Count());
       
   848     ConstructL(count);
       
   849     
       
   850     for (TUint i(0); (i < count); i++)
       
   851         {
       
   852         AppendL(aElements[i]);
       
   853         }
       
   854     }
       
   855     
       
   856 void CMTPTypeArray::AppendL(const TAny* aElement)
       
   857     {    
       
   858     const TUint index(NumElements());
       
   859     TUint32 numElements(index + 1);
       
   860     
       
   861     if (iBuffer.MaxLength() < BufferSize(numElements))
       
   862         {
       
   863         ReAllocBufferL(numElements);
       
   864         }
       
   865 
       
   866     memcpy(&iBuffer[Offset(index)], aElement, iElementSize);
       
   867     SetNumElements(numElements);
       
   868     }
       
   869     
       
   870 void CMTPTypeArray::Element(TUint aIndex, TAny* aElement) const
       
   871     {
       
   872     __ASSERT_ALWAYS((aIndex < NumElements()), Panic(EMTPTypeBoundsError));
       
   873     memcpy(aElement, &iBuffer[Offset(aIndex)], iElementSize);
       
   874     }
       
   875     
       
   876 void CMTPTypeArray::ReAllocBufferL(TUint32 aNumElements)
       
   877     {
       
   878     TInt currentSize(iBuffer.MaxLength());
       
   879     TUint64 newSize(BufferSize(aNumElements));
       
   880     
       
   881     if (newSize != currentSize)
       
   882         {
       
   883         if (newSize > KMaxTInt)
       
   884             {
       
   885             SetInvalidL();
       
   886             }
       
   887         else
       
   888             {
       
   889             if (newSize < currentSize)
       
   890                 {
       
   891                 // Buffer is shrinking.
       
   892                 iBuffer.Close();   
       
   893                 }
       
   894             iBuffer.ReAllocL(newSize);
       
   895             iBuffer.SetMax();
       
   896             SetNumElements(aNumElements);   
       
   897             }
       
   898         }
       
   899     }
       
   900 
       
   901 void CMTPTypeArray::SetNumElements(TUint32 aNumElements)
       
   902     {
       
   903     memcpy(&iBuffer[KMTPNumElementsOffset], &aNumElements, KMTPNumElementsLen);
       
   904     }
       
   905 
       
   906 TUint64 CMTPTypeArray::BufferSize(TUint32 aNumElements) const
       
   907     {
       
   908     return ((iElementSize * aNumElements) + KMTPNumElementsLen);
       
   909     }
       
   910     
       
   911 TUint CMTPTypeArray::Offset(TUint aIndex) const
       
   912     {
       
   913     return (KMTPFirstElementOffset + (aIndex * iElementSize));
       
   914     }
       
   915     
       
   916 void CMTPTypeArray::SetInvalidL()
       
   917     {
       
   918     iValidationState = KMTPDataTypeInvalid;
       
   919     User::Leave(iValidationState);
       
   920     }
       
   921     
       
   922 void CMTPTypeArray::SimpleArrayTypeMetaDataL(TInt aArrayType, TInt& aElementType, TUint& aElementSize)
       
   923     {            
       
   924     switch (aArrayType)
       
   925         {
       
   926     case EMTPTypeAINT8:
       
   927         aElementType    = EMTPTypeINT8;
       
   928         aElementSize    = KMTPTypeINT8Size;
       
   929         break; 
       
   930         
       
   931     case EMTPTypeAUINT8:
       
   932         aElementType    = EMTPTypeUINT8;
       
   933         aElementSize    = KMTPTypeUINT8Size;
       
   934         break; 
       
   935         
       
   936     case EMTPTypeAINT16:
       
   937         aElementType    = EMTPTypeINT16;
       
   938         aElementSize    = KMTPTypeINT16Size;
       
   939         break; 
       
   940         
       
   941     case EMTPTypeAUINT16:
       
   942         aElementType    = EMTPTypeUINT16;
       
   943         aElementSize    = KMTPTypeUINT16Size;
       
   944         break; 
       
   945         
       
   946     case EMTPTypeAINT32:
       
   947         aElementType    = EMTPTypeINT32;
       
   948         aElementSize    = KMTPTypeINT32Size;
       
   949         break; 
       
   950         
       
   951     case EMTPTypeAUINT32:
       
   952         aElementType    = EMTPTypeUINT32;
       
   953         aElementSize    = KMTPTypeUINT32Size;
       
   954         break; 
       
   955         
       
   956     case EMTPTypeAINT64:
       
   957         aElementType    = EMTPTypeINT64;
       
   958         aElementSize    = KMTPTypeINT64Size;
       
   959         break; 
       
   960         
       
   961     case EMTPTypeAUINT64:
       
   962         aElementType    = EMTPTypeUINT64;
       
   963         aElementSize    = KMTPTypeUINT64Size;
       
   964         break; 
       
   965         
       
   966     case EMTPTypeAINT128:
       
   967         aElementType    = EMTPTypeINT128;
       
   968         aElementSize    = KMTPTypeINT128Size;
       
   969         break; 
       
   970         
       
   971     case EMTPTypeAUINT128:
       
   972         aElementType    = EMTPTypeUINT128;
       
   973         aElementSize    = KMTPTypeUINT128Size;
       
   974         break; 
       
   975         
       
   976     default:
       
   977         User::Leave(KErrArgument);
       
   978         } 
       
   979     }