symport/e32/euser/cbase/ub_array.cpp
changeset 1 0a7b44b10206
child 2 806186ab5e14
equal deleted inserted replaced
0:c55016431358 1:0a7b44b10206
       
     1 // Copyright (c) 1994-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 the License "Symbian Foundation License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.symbianfoundation.org/legal/sfl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\euser\cbase\ub_array.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "ub_std.h"
       
    19 
       
    20 struct SVarRec
       
    21 	{
       
    22 	TInt len;
       
    23 	TAny *data;
       
    24 	};
       
    25 
       
    26 NONSHARABLE_CLASS(TSwapArray) : public TSwap
       
    27 	{
       
    28 public:
       
    29 	inline TSwapArray(CBufBase *aBase,TInt aRecordLength);
       
    30 	TUint8 *At(TInt anIndex) const;
       
    31 	virtual void Swap(TInt aLeft,TInt aRight) const;
       
    32 private:
       
    33 	CBufBase *iBase;
       
    34 	TInt iLength;
       
    35 	};
       
    36 inline TSwapArray::TSwapArray(CBufBase *aBase,TInt aRecordLength)
       
    37 	: iBase(aBase),iLength(aRecordLength)
       
    38 	{}
       
    39 
       
    40 TUint8 *TSwapArray::At(TInt anIndex) const
       
    41 //
       
    42 // Return a pointer to the array element
       
    43 //
       
    44 	{
       
    45 	
       
    46 	return((TUint8 *)iBase->Ptr(anIndex*iLength).Ptr());
       
    47 	}
       
    48 
       
    49 void TSwapArray::Swap(TInt aLeft,TInt aRight) const
       
    50 //
       
    51 // Swap two elements of the array.
       
    52 //
       
    53 	{
       
    54 	
       
    55 	Mem::Swap(At(aLeft),At(aRight),iLength);
       
    56 	}
       
    57 
       
    58 
       
    59 
       
    60 
       
    61 EXPORT_C TKeyArrayFix::TKeyArrayFix(TInt anOffset,TKeyCmpText aType)
       
    62 	: TKey(anOffset,aType)
       
    63 /**
       
    64 Constructs the characteristics of a descriptor key.
       
    65 
       
    66 No length value is passed as this is taken from the descriptor type key.
       
    67 
       
    68 @param anOffset The offset of the key from the start of an array element.
       
    69 @param aType    An enumeration which defines the type of comparison to be made 
       
    70                 between two descriptor keys.
       
    71 @see TKeyCmpText
       
    72 */
       
    73 	{}
       
    74 
       
    75 
       
    76 
       
    77 
       
    78 EXPORT_C TKeyArrayFix::TKeyArrayFix(TInt anOffset,TKeyCmpText aType,TInt aLength)
       
    79 	: TKey(anOffset,aType,aLength)
       
    80 /**
       
    81 Constructs the characteristics of a text key.
       
    82 
       
    83 @param anOffset The offset of the key from the start of an array element.
       
    84 @param aType    An enumeration which defines the type of comparison to be made 
       
    85                 between two text keys.
       
    86 @param aLength The length of the text key.
       
    87 
       
    88 @see TKeyCmpText
       
    89 */
       
    90 	{}
       
    91 
       
    92 
       
    93 
       
    94 
       
    95 EXPORT_C TKeyArrayFix::TKeyArrayFix(TInt anOffset,TKeyCmpNumeric aType)
       
    96 	: TKey(anOffset,aType)
       
    97 /**
       
    98 Constructs the characteristics of a numeric key.
       
    99 
       
   100 @param anOffset The offset of the key from the start of an array element.
       
   101 @param aType    An enumeration which defines the type of the numeric key.
       
   102 
       
   103 @see TKeyCmpNumeric
       
   104 */
       
   105 	{}
       
   106 
       
   107 
       
   108 
       
   109 
       
   110 EXPORT_C void TKeyArrayFix::Set(CBufBase *aBase,TInt aRecordLength)
       
   111 //
       
   112 // Set the base and record length
       
   113 //
       
   114 	{
       
   115 
       
   116 	iBase=aBase;
       
   117 	iRecordLength=aRecordLength;
       
   118 	}
       
   119 
       
   120 EXPORT_C TAny *TKeyArrayFix::At(TInt anIndex) const
       
   121 //
       
   122 // Return an address in the array.
       
   123 //
       
   124 	{
       
   125 
       
   126 	if (anIndex==KIndexPtr)
       
   127 		return((TUint8 *)iPtr+iKeyOffset); 			
       
   128 	return((TAny *)(iBase->Ptr(anIndex*iRecordLength).Ptr()+iKeyOffset));
       
   129 	}
       
   130 
       
   131 
       
   132 
       
   133 
       
   134 EXPORT_C TKeyArrayVar::TKeyArrayVar(TInt anOffset,TKeyCmpText aType)
       
   135 	: TKey(anOffset,aType)
       
   136 /**
       
   137 Constructs the characteristics of a descriptor key.
       
   138 
       
   139 No length value is passed as this is taken from the descriptor type key.
       
   140 
       
   141 @param anOffset The offset of the key from the start of an array element.
       
   142 @param aType    An enumeration which defines the type of comparison to be made 
       
   143                 between two descriptor keys.
       
   144                 
       
   145 @see TKeyCmpText
       
   146 */
       
   147 	{}
       
   148 
       
   149 
       
   150 
       
   151 
       
   152 EXPORT_C TKeyArrayVar::TKeyArrayVar(TInt anOffset,TKeyCmpText aType,TInt aLength)
       
   153 	: TKey(anOffset,aType,aLength)
       
   154 /**
       
   155 Constructs the characteristics of a text key.
       
   156 
       
   157 @param anOffset The offset of the key from the start of an array element.
       
   158 @param aType    An enumeration which defines the type of comparison to be made 
       
   159                 between two text keys.
       
   160 @param aLength  The length of the text key.
       
   161 
       
   162 @see TKeyCmpText
       
   163 */
       
   164 	{}
       
   165 
       
   166 
       
   167 
       
   168 
       
   169 EXPORT_C TKeyArrayVar::TKeyArrayVar(TInt anOffset,TKeyCmpNumeric aType)
       
   170 	: TKey(anOffset,aType)
       
   171 /**
       
   172 Constructs the characteristics of a numeric key.
       
   173 
       
   174 @param anOffset The offset of the key from the start of an array element.
       
   175 @param aType    An enumeration which defines the type of the numeric key.
       
   176 
       
   177 @see TKeyCmpNumeric
       
   178 */
       
   179 	{}
       
   180 
       
   181 
       
   182 
       
   183 
       
   184 EXPORT_C void TKeyArrayVar::Set(CBufBase *aBase)
       
   185 //
       
   186 // Set the private variable iBase to aBase.
       
   187 //
       
   188 	{
       
   189 
       
   190 	iBase=aBase;
       
   191 	}
       
   192 
       
   193 EXPORT_C TAny *TKeyArrayVar::At(TInt anIndex) const
       
   194 //
       
   195 // Return an address in the array.
       
   196 //
       
   197 	{
       
   198 
       
   199 	if (anIndex==KIndexPtr)
       
   200 		return((TUint8 *)iPtr+iKeyOffset);   
       
   201 	SVarRec *pV=(SVarRec *)iBase->Ptr(anIndex*sizeof(SVarRec)).Ptr();
       
   202 	return(((TUint8 *)pV->data)+iKeyOffset);
       
   203 	}
       
   204 
       
   205 
       
   206 
       
   207 
       
   208 EXPORT_C TKeyArrayPak::TKeyArrayPak(TInt anOffset,TKeyCmpText aType)
       
   209 	: TKeyArrayVar(anOffset,aType)
       
   210 /**
       
   211 Constructs the characteristics of a descriptor key.
       
   212 
       
   213 No length value is passed as this is taken from the descriptor type key.
       
   214 
       
   215 @param anOffset The offset of the key from the start of an array element.
       
   216 @param aType    An enumeration which defines the type of comparison to be made 
       
   217                 between two descriptor keys.
       
   218                 
       
   219 @see TKeyCmpText
       
   220 */
       
   221 	{}
       
   222 
       
   223 
       
   224 
       
   225 
       
   226 EXPORT_C TKeyArrayPak::TKeyArrayPak(TInt anOffset,TKeyCmpText aType,TInt aLength)
       
   227 	: TKeyArrayVar(anOffset,aType,aLength)
       
   228 /**
       
   229 Constructs the characteristics of a text key.
       
   230 
       
   231 @param anOffset The offset of the key from the start of an array element.
       
   232 @param aType    An enumeration which defines the type of comparison to be made 
       
   233                 between two text keys.
       
   234 @param aLength  The length of the text key.
       
   235 
       
   236 @see TKeyCmpText
       
   237 */
       
   238 	{}
       
   239 
       
   240 
       
   241 
       
   242 
       
   243 EXPORT_C TKeyArrayPak::TKeyArrayPak(TInt anOffset,TKeyCmpNumeric aType)
       
   244 	: TKeyArrayVar(anOffset,aType)
       
   245 /**
       
   246 Constructs the characteristics of a numeric key.
       
   247 
       
   248 @param anOffset The offset of the key from the start of an array element.
       
   249 @param aType    An enumeration which defines the type of the numeric key.
       
   250 
       
   251 @see TKeyCmpNumeric
       
   252 */
       
   253 	{}
       
   254 
       
   255 
       
   256 
       
   257 
       
   258 EXPORT_C void TKeyArrayPak::Set(CBufBase *aBase)
       
   259 //
       
   260 // Set the private variable iBase to aBase.
       
   261 //
       
   262 	{
       
   263 
       
   264 	iBase=aBase;
       
   265 	iCacheIndex=0;
       
   266 	iCacheOffset=0;
       
   267 	}
       
   268 
       
   269 EXPORT_C TAny *TKeyArrayPak::At(TInt anIndex) const
       
   270 //
       
   271 // Return a pointer to the data in the record with index anIndex.
       
   272 //
       
   273 	{
       
   274 //
       
   275 // When anIndex is equal to KIndexPtr (HighValues) this means that we should return the address of
       
   276 // the iPtr+iKeyOffset which will have been set up by the TKeyArrayPak constructor.
       
   277 //
       
   278 	if (anIndex==KIndexPtr)
       
   279 		return((TUint8 *)iPtr+iKeyOffset); 
       
   280 //
       
   281 // Otherwise get the offset into the buffer of the record with index anIndex.
       
   282 //
       
   283 	TInt offset=0;
       
   284  	TInt curIndex=0;
       
   285 	if (iCacheIndex<=anIndex)
       
   286 		{
       
   287 		curIndex=iCacheIndex;
       
   288 		offset=iCacheOffset;
       
   289 		}
       
   290 	TAny *pRecord=(TAny *)iBase->Ptr(offset).Ptr();
       
   291 	while (curIndex<anIndex)
       
   292 		{
       
   293 		TInt lenData=(*(TInt *)pRecord);
       
   294 		offset+=Align4(lenData)+sizeof(TUint);
       
   295 		pRecord=(TAny *)iBase->Ptr(offset).Ptr();
       
   296 		curIndex++;
       
   297 		}
       
   298 	(TInt &)iCacheIndex=anIndex;
       
   299 	(TInt &)iCacheOffset=offset;
       
   300 	TAny *pData=(TAny *)((TInt *)pRecord + 1);
       
   301  	return((TUint8 *)pData+iKeyOffset);
       
   302 	}
       
   303 
       
   304 EXPORT_C CArrayFixBase::CArrayFixBase(TBufRep aRep,TInt aRecordLength,TInt aGranularity)
       
   305 //
       
   306 // Constructor
       
   307 //
       
   308 /**
       
   309 @internalComponent
       
   310 */
       
   311 	{
       
   312 
       
   313 	__ASSERT_ALWAYS(aRecordLength>0,Panic(EArrayFixInvalidLength));
       
   314 	__ASSERT_ALWAYS(aGranularity>0,Panic(EArrayFixInvalidGranularity));
       
   315 //	iCount=0;
       
   316 //	iBase=NULL;
       
   317 	iLength=aRecordLength;
       
   318 	iGranularity=aGranularity;
       
   319 	iCreateRep=aRep;
       
   320 	}
       
   321 
       
   322 EXPORT_C CArrayFixBase::~CArrayFixBase()
       
   323 /**
       
   324 Destructor.
       
   325 
       
   326 This frees all resources owned by the object, prior to its destruction.
       
   327 */
       
   328 	{
       
   329 
       
   330 	delete iBase;
       
   331 	}
       
   332 
       
   333 EXPORT_C void CArrayFixBase::Compress()
       
   334 /**
       
   335 Compresses the array.
       
   336 
       
   337 The function removes the excess space from the array buffer. The effect is 
       
   338 to reduce the memory allocated to the array buffer so that it is just
       
   339 sufficient to contain the elements of the array. This applies to both flat
       
   340 and segmented array buffers.
       
   341 
       
   342 If the array is empty, then the memory allocated to the array buffer is freed.
       
   343 */
       
   344 	{
       
   345 
       
   346 	if (iBase)
       
   347 		iBase->Compress();
       
   348 	}
       
   349 
       
   350 EXPORT_C void CArrayFixBase::Reset()
       
   351 /**
       
   352 Deletes all elements from the array and frees the memory allocated 
       
   353 to the array buffer.
       
   354 */
       
   355 	{
       
   356 
       
   357 	iCount=0;
       
   358 	if (iBase)
       
   359 		iBase->Reset();
       
   360 	}
       
   361 
       
   362 EXPORT_C TInt CArrayFixBase::Sort(TKeyArrayFix &aKey)
       
   363 /**
       
   364 Sorts the elements of the array into key sequence.
       
   365 
       
   366 @param aKey The key object defining the properties of the key. 
       
   367 
       
   368 @return KErrNone if the sort completes successfully.
       
   369         KErrGeneral if the stack overflows
       
   370 */
       
   371 	{
       
   372 
       
   373 	if (iCount==0)
       
   374 		return KErrNone;
       
   375 	TSwapArray aSwap(iBase,iLength);
       
   376 	SetKey(aKey);
       
   377 	return(User::QuickSort(iCount,aKey,aSwap));
       
   378 	}
       
   379 
       
   380 EXPORT_C TAny *CArrayFixBase::At(TInt anIndex) const
       
   381 //
       
   382 // Index into the array.
       
   383 //
       
   384 /**
       
   385 @internalComponent
       
   386 */
       
   387 	{
       
   388 
       
   389 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
       
   390 	return((TAny *)iBase->Ptr(anIndex*iLength).Ptr());
       
   391 	}
       
   392 
       
   393 EXPORT_C TAny *CArrayFixBase::End(TInt anIndex) const
       
   394 //
       
   395 // Return a pointer past contiguous elements starting at anIndex.
       
   396 //
       
   397 /**
       
   398 @internalComponent
       
   399 */
       
   400 	{
       
   401 
       
   402 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
       
   403 	TPtr8 p=iBase->Ptr(anIndex*iLength);
       
   404 	return((TAny *)(p.Ptr()+p.Length()));
       
   405 	}
       
   406 
       
   407 EXPORT_C TAny *CArrayFixBase::Back(TInt anIndex) const
       
   408 //
       
   409 // Return a pointer to contiguous elements before anIndex.
       
   410 //
       
   411 /**
       
   412 @internalComponent
       
   413 */
       
   414 	{
       
   415 
       
   416 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
       
   417 	TPtr8 p=iBase->BackPtr(anIndex*iLength);
       
   418 	return((TAny *)p.Ptr());
       
   419 	}
       
   420 
       
   421 EXPORT_C void CArrayFixBase::Delete(TInt anIndex)
       
   422 /**
       
   423 Deletes a single element from the array at a specified position.
       
   424 
       
   425 Deleting elements from the array does not cause the array buffer to be
       
   426 automatically compressed. Call CArrayFixBase::Compress() to return excess space
       
   427 to the heap.
       
   428 
       
   429 @param anIndex The position within the array at which to delete the element, 
       
   430                This is a value relative to zero. 
       
   431 
       
   432 @panic E32USER-CBase 21, if anIndex is negative or is greater 
       
   433                          than or equal to the number of elements currently
       
   434                          in the array.
       
   435 @see CArrayFixBase::Compress
       
   436 */
       
   437 	{
       
   438 
       
   439 	Delete(anIndex,1);
       
   440 	}
       
   441 
       
   442 EXPORT_C void CArrayFixBase::Delete(TInt anIndex,TInt aCount)
       
   443 /**
       
   444 Deletes one or more contiguous elements from the array, starting at a specific 
       
   445 position.
       
   446 
       
   447 Deleting elements from the array does not cause the array buffer to be
       
   448 automatically compressed. Call CArrayFixBase::Compress() to return excess space
       
   449 to the heap.
       
   450 
       
   451 @param anIndex The position within the array from where deletion of elements 
       
   452                is to start. The position is relative to zero, i.e. zero implies
       
   453                that elements, starting with the first, are deleted from the
       
   454                array.
       
   455                 
       
   456 @param aCount  The number of contiguous elements to be deleted from the array. 
       
   457   
       
   458 @panic E32USER-CBase 21, if anIndex is negative, or is greater than or equal to
       
   459                          the number of elements currently in the array.
       
   460 @panic E32USER-CBase 22, if aCount is negative.
       
   461 @panic E32USER-CBase 29, if the sum of anIndex and aCount is greater than or equal
       
   462                          to the number of elements currently in the array.
       
   463 */
       
   464 	{
       
   465 
       
   466 	if (aCount==0)
       
   467 		return;
       
   468 	__ASSERT_ALWAYS(aCount>0,Panic(EArrayCountNegative));
       
   469 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
       
   470 	__ASSERT_ALWAYS(anIndex+aCount<=iCount,Panic(EArrayCountTooBig));
       
   471 	iBase->Delete(anIndex*iLength,aCount*iLength);
       
   472 	iCount-=aCount;
       
   473 	}
       
   474 
       
   475 EXPORT_C TAny *CArrayFixBase::ExpandL(TInt anIndex)
       
   476 //
       
   477 // Expand the array to make room for a new record at anIndex.
       
   478 //
       
   479 /**
       
   480 @internalComponent
       
   481 */
       
   482 	{
       
   483 
       
   484 	if (iBase==NULL)
       
   485 		iBase=(*iCreateRep)(iLength*iGranularity);
       
   486 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
       
   487 	iBase->ExpandL(anIndex*iLength,iLength);
       
   488 	++iCount;
       
   489 	return((TAny *)iBase->Ptr(anIndex*iLength).Ptr());
       
   490 	}
       
   491 
       
   492 EXPORT_C TInt CArrayFixBase::Find(const TAny *aPtr,TKeyArrayFix &aKey,TInt &anIndex) const
       
   493 //
       
   494 // Find in the array using a sequential search.
       
   495 //
       
   496 /**
       
   497 @internalComponent
       
   498 */
       
   499 	{
       
   500 
       
   501 	if (iCount==0)
       
   502 	    {
       
   503 	    anIndex=0;
       
   504 		return(-1);
       
   505 		}
       
   506 	aKey.SetPtr(aPtr);
       
   507 	SetKey(aKey);
       
   508 	TInt r=1;
       
   509 	TInt i=0;
       
   510 	while (i<Count())
       
   511 		{
       
   512 		TInt j=aKey.Compare(i,KIndexPtr);
       
   513 		if (j==0)
       
   514 			{
       
   515 			r=j;
       
   516 			break;
       
   517 			}
       
   518 		i++;
       
   519 		}
       
   520 	anIndex=i;
       
   521 	return(r);
       
   522 	}
       
   523 
       
   524 EXPORT_C TInt CArrayFixBase::FindIsq(const TAny *aPtr,TKeyArrayFix &aKey,TInt &anIndex) const
       
   525 //
       
   526 // Find in the array using a binary search.
       
   527 //
       
   528 /**
       
   529 @internalComponent
       
   530 */
       
   531 	{
       
   532 
       
   533 	if (iCount==0)
       
   534 	    {
       
   535 	    anIndex=0;
       
   536 		return(-1);
       
   537 		}
       
   538 	aKey.SetPtr(aPtr);
       
   539 	SetKey(aKey);
       
   540     return(User::BinarySearch(Count(),aKey,anIndex));
       
   541 	}
       
   542 
       
   543 EXPORT_C void CArrayFixBase::InsertL(TInt anIndex,const TAny *aPtr)
       
   544 //													  
       
   545 // Insert a record into the array.
       
   546 //
       
   547 /**
       
   548 @internalComponent
       
   549 */
       
   550 	{
       
   551 
       
   552 	InsertL(anIndex,aPtr,1);
       
   553 	}
       
   554 
       
   555 EXPORT_C void CArrayFixBase::InsertL(TInt anIndex,const TAny *aPtr,TInt aCount)
       
   556 //													  
       
   557 // Insert aCount records into the array.
       
   558 //
       
   559 /**
       
   560 @internalComponent
       
   561 */
       
   562 	{
       
   563 
       
   564 	if (aCount==0)
       
   565 		return;
       
   566 	if (iBase==NULL)
       
   567 		iBase=(*iCreateRep)(iLength*iGranularity);
       
   568 	__ASSERT_ALWAYS(aCount>0,Panic(EArrayCountNegative2));
       
   569 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
       
   570 	iBase->InsertL(anIndex*iLength,aPtr,aCount*iLength);
       
   571 	iCount+=aCount;
       
   572 	}
       
   573 
       
   574 EXPORT_C void CArrayFixBase::InsertRepL(TInt anIndex,const TAny *aPtr,TInt aReplicas)
       
   575 //													  
       
   576 // Insert aReplicas copies  of a record into the array.
       
   577 //
       
   578 /**
       
   579 @internalComponent
       
   580 */
       
   581 	{
       
   582 
       
   583 	if (aReplicas==0)
       
   584 		return;
       
   585 	if (iBase==NULL)
       
   586 		iBase=(*iCreateRep)(iLength*iGranularity);
       
   587 	__ASSERT_ALWAYS(aReplicas>0,Panic(EArrayReplicasNegative));
       
   588 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
       
   589 	TInt pos=anIndex*iLength;
       
   590 	TInt len=aReplicas*iLength;
       
   591 	iBase->ExpandL(pos,len);
       
   592 	for (TInt end=pos+len;pos<end;pos+=iLength)
       
   593 		iBase->Write(pos,aPtr,iLength);
       
   594 	iCount+=aReplicas;
       
   595 	}
       
   596 
       
   597 EXPORT_C TInt CArrayFixBase::InsertIsqL(const TAny *aPtr,TKeyArrayFix &aKey)
       
   598 //
       
   599 // Insert in sequence, no duplicates allowed.
       
   600 //
       
   601 /**
       
   602 @internalComponent
       
   603 */
       
   604 	{
       
   605 
       
   606 	TInt i=0;
       
   607 	TInt r=FindIsq(aPtr,aKey,i);
       
   608 	if (r==0) // a duplicate, leave
       
   609 		User::Leave(KErrAlreadyExists);
       
   610 	InsertL(i,aPtr,1);
       
   611 	return(i);
       
   612 	}
       
   613 
       
   614 EXPORT_C TInt CArrayFixBase::InsertIsqAllowDuplicatesL(const TAny *aPtr,TKeyArrayFix &aKey)
       
   615 //
       
   616 // Insert in sequence, allow duplicates.
       
   617 //
       
   618 /**
       
   619 @internalComponent
       
   620 */
       
   621 	{
       
   622 
       
   623 	TInt i=0;
       
   624 	TInt r=FindIsq(aPtr,aKey,i);
       
   625 	if (r==0) // a duplicate, insert after
       
   626 		++i;
       
   627 	InsertL(i,aPtr,1);
       
   628 	return(i);
       
   629 	}
       
   630 
       
   631 EXPORT_C void CArrayFixBase::ResizeL(TInt aCount,const TAny *aPtr)
       
   632 //
       
   633 // Resize the array to contain aCount records, copying a record into any new slots.
       
   634 //
       
   635 /**
       
   636 @internalComponent
       
   637 */
       
   638 	{
       
   639 
       
   640 	__ASSERT_ALWAYS(aCount>=0,Panic(EArrayCountNegative3));
       
   641 	TInt excess=iCount-aCount;
       
   642 	if (excess>0)
       
   643 		Delete(aCount,excess);
       
   644 	else
       
   645 		InsertRepL(iCount,aPtr,-excess);
       
   646 	}
       
   647 
       
   648 EXPORT_C void CArrayFixBase::SetReserveFlatL(TInt aCount) 
       
   649 //
       
   650 // Reserve space to contain aCount items. Only for flat arrays!
       
   651 //
       
   652 /**
       
   653 @internalComponent
       
   654 */
       
   655 	{
       
   656 
       
   657 	__ASSERT_ALWAYS(aCount>=iCount,Panic(EArrayReserveTooSmall));
       
   658 	if (iBase==NULL)
       
   659 		iBase=(*iCreateRep)(iLength*iGranularity);
       
   660 	((CBufFlat*)iBase)->SetReserveL(iLength*aCount);		// dodgy cast. Can we assert the type?
       
   661 	}
       
   662 
       
   663 EXPORT_C void CArrayFixBase::SetKey(TKeyArrayFix &aKey) const
       
   664 //
       
   665 // Set the key data.
       
   666 //
       
   667 /**
       
   668 @internalComponent
       
   669 */
       
   670 	{
       
   671 
       
   672 	aKey.Set(iBase,iLength);
       
   673 	}
       
   674 
       
   675 EXPORT_C TInt CArrayFixBase::CountR(const CBase *aPtr)
       
   676 //
       
   677 // Return the number of items in the array.
       
   678 //
       
   679 /**
       
   680 @internalComponent
       
   681 */
       
   682 	{
       
   683 
       
   684 	return(((CArrayFixBase *)aPtr)->Count());
       
   685 	}
       
   686 
       
   687 EXPORT_C const TAny *CArrayFixBase::AtR(const CBase *aPtr,TInt anIndex)
       
   688 //
       
   689 // Return the address of an item in the array.
       
   690 //
       
   691 /**
       
   692 @internalComponent
       
   693 */
       
   694 	{
       
   695 
       
   696 	return(((CArrayFixBase *)aPtr)->At(anIndex));
       
   697 	}
       
   698 
       
   699 EXPORT_C CArrayVarBase::CArrayVarBase(TBufRep aRep,TInt aGranularity)
       
   700 //
       
   701 // Constructor
       
   702 //
       
   703 /**
       
   704 @internalComponent
       
   705 */
       
   706 	{
       
   707 
       
   708 	__ASSERT_ALWAYS(aGranularity>0,Panic(EArrayVarInvalidGranularity));
       
   709 //	iCount=0;
       
   710 //	iBase=NULL;
       
   711 	iGranularity=aGranularity;
       
   712 	iCreateRep=aRep;
       
   713 	}
       
   714 
       
   715 EXPORT_C CArrayVarBase::~CArrayVarBase()
       
   716 /**
       
   717 Destructor.
       
   718 
       
   719 Frees all resources owned by the object, prior to its destruction.
       
   720 */
       
   721 	{
       
   722 
       
   723 	if (iBase)
       
   724 		{
       
   725 		Reset();
       
   726 		delete iBase;
       
   727 		}
       
   728 	}
       
   729 
       
   730 EXPORT_C TInt CArrayVarBase::Length(TInt anIndex) const
       
   731 /**
       
   732 Gets the length of a specific element.
       
   733 
       
   734 @param anIndex The position of the element within the array. The position 
       
   735                is relative to zero, (i.e. the first element in the array is
       
   736                at position 0). 
       
   737 
       
   738 @return The length of the element at position anIndex.
       
   739 
       
   740 @panic E32USER-CBase 21, if anIndex is negative or is greater than the number
       
   741        of elements currently in the array.
       
   742 */
       
   743 	{
       
   744 
       
   745 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
       
   746 	return(((SVarRec *)iBase->Ptr(anIndex*sizeof(SVarRec)).Ptr())->len);
       
   747 	}
       
   748 
       
   749 EXPORT_C void CArrayVarBase::Compress()
       
   750 /**
       
   751 Removes excess space from the array buffer.
       
   752 
       
   753 The effect is to reduce the memory allocated to the array buffer so that it is
       
   754 just sufficient to represent the array. This applies to both flat and segmented
       
   755 array buffers.
       
   756 
       
   757 If the array is empty, then the memory allocated to the array buffer is freed.
       
   758 */
       
   759 	{
       
   760 
       
   761 	if (iBase)
       
   762 		iBase->Compress();
       
   763 	}
       
   764 
       
   765 EXPORT_C void CArrayVarBase::Reset()
       
   766 /**
       
   767 Deletes all elements from the array and frees the memory allocated to the array 
       
   768 buffer.
       
   769 
       
   770 As each element of a variable array is contained within its own heap cell, 
       
   771 this function has the effect of freeing all such cells.
       
   772 */
       
   773 	{
       
   774 
       
   775 	Delete(0,Count());
       
   776 	}
       
   777 
       
   778 EXPORT_C TInt CArrayVarBase::Sort(TKeyArrayVar &aKey)
       
   779 /**
       
   780 Sorts the elements of the array into key sequence.
       
   781 
       
   782 @param aKey The key object defining the properties of the key. 
       
   783 
       
   784 @return KErrNone, if the sort completes successfully.
       
   785         KErrGeneral, if the stack overflows.
       
   786 */
       
   787 	{
       
   788 
       
   789 	if (iCount==0)
       
   790 		return KErrNone;
       
   791 	TSwapArray aSwap(iBase,sizeof(SVarRec));
       
   792 	SetKey(aKey);
       
   793 	return(User::QuickSort(iCount,aKey,aSwap));
       
   794 	}
       
   795 
       
   796 EXPORT_C TAny * CArrayVarBase::At(TInt anIndex) const
       
   797 //
       
   798 // Return a pointer to the data in the array.
       
   799 //
       
   800 /**
       
   801 @internalComponent
       
   802 */
       
   803 	{
       
   804 
       
   805 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
       
   806 	return(((SVarRec *)iBase->Ptr(anIndex*sizeof(SVarRec)).Ptr())->data);
       
   807 	}
       
   808 
       
   809 EXPORT_C void CArrayVarBase::Delete(TInt anIndex)
       
   810 /**
       
   811 Removes one element from the array.
       
   812 
       
   813 Deleting elements from the array does not cause the array buffer to be
       
   814 automatically compressed. Call CArrayVarBase::Compress() to return excess
       
   815 space to the heap.
       
   816 
       
   817 @param anIndex The position within the array of the element to delete. The 
       
   818                position is relative to zero.
       
   819                
       
   820 @panic E32USER-CBase 21, if anIndex is negative or  greater than the number
       
   821        of elements currently in the array.
       
   822 */
       
   823 	{
       
   824 
       
   825 	Delete(anIndex,1);
       
   826 	}
       
   827 
       
   828 EXPORT_C void CArrayVarBase::Delete(TInt anIndex,TInt aCount)
       
   829 /**
       
   830 Removes one or more contiguous elements from the array, starting at the
       
   831 specified position.
       
   832 
       
   833 Deleting elements from the array does not cause the array buffer to be
       
   834 automatically compressed. Call CArrayVarBase::Compress() to return excess
       
   835 space to the heap.
       
   836 
       
   837 @param anIndex The position within the array from where deletion of elements is
       
   838                to start. The position is relative to zero, i.e. zero implies
       
   839                that elements, starting with the first, are deleted from the
       
   840                array.
       
   841 
       
   842 @param aCount  The number of elements to be deleted from the array.
       
   843 
       
   844 @panic E32USER-CBase 21, if anIndex is negative or greater than or equal to the
       
   845        number of elements currently in the array.
       
   846 @panic E32USER-CBase 25, if aCount is negative.
       
   847 @panic E32USER-CBase 29, if the sum of anIndexPos and aCount is greater than
       
   848        the number of elements currently in the array.
       
   849 */
       
   850 	{
       
   851 
       
   852 	if (aCount==0)
       
   853 		return;
       
   854 	__ASSERT_ALWAYS(aCount>0,Panic(EArrayCountNegative4));
       
   855 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
       
   856 	TInt end=anIndex+aCount;
       
   857 	__ASSERT_ALWAYS(end<=iCount,Panic(EArrayCountTooBig));
       
   858 	for (TInt i=anIndex;i<end;i++)
       
   859 		{
       
   860 		TPtr8 p=iBase->Ptr(i*sizeof(SVarRec));
       
   861 		User::Free(((SVarRec *)p.Ptr())->data);
       
   862 		}
       
   863 	iBase->Delete(anIndex*sizeof(SVarRec),aCount*sizeof(SVarRec));
       
   864 	iCount-=aCount;
       
   865 	}
       
   866 
       
   867 EXPORT_C TAny *CArrayVarBase::ExpandL(TInt anIndex,TInt aLength)
       
   868 //
       
   869 // Expand the array at anIndex.
       
   870 //
       
   871 /**
       
   872 @internalComponent
       
   873 */
       
   874 	{
       
   875 
       
   876 	if (iBase==NULL)
       
   877 		iBase=(*iCreateRep)(sizeof(SVarRec)*iGranularity);
       
   878 	__ASSERT_ALWAYS(aLength>=0,Panic(EArrayLengthNegative));
       
   879 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
       
   880 	TAny *pV=User::AllocL(aLength);
       
   881 	SVarRec s;
       
   882 	s.data=pV;
       
   883 	s.len=aLength;
       
   884 	TRAPD(r,iBase->InsertL(anIndex*sizeof(SVarRec),&s,sizeof(SVarRec)));
       
   885 	if (r!=KErrNone)
       
   886 		{
       
   887 		User::Free(pV);
       
   888 		User::Leave(r);
       
   889 		}
       
   890 	iCount++;
       
   891 	return(pV);
       
   892 	}
       
   893 
       
   894 EXPORT_C TInt CArrayVarBase::Find(const TAny *aPtr,TKeyArrayVar &aKey,TInt &anIndex) const
       
   895 //
       
   896 // Find using a sequential search.
       
   897 //
       
   898 /**
       
   899 @internalComponent
       
   900 */
       
   901 	{
       
   902 
       
   903 	if (iCount==0)
       
   904 	    {
       
   905 	    anIndex=0;
       
   906 		return(-1);
       
   907 		}
       
   908 	aKey.SetPtr(aPtr);
       
   909 	SetKey(aKey);
       
   910 	TInt ret=(-1);
       
   911 	TInt i=0;
       
   912 	while (i<Count())
       
   913 		{
       
   914 		TInt j=aKey.Compare(i,KIndexPtr);
       
   915 		if (j==0)
       
   916 			{
       
   917 			ret=j;
       
   918 			break;
       
   919 			}
       
   920 		i++;
       
   921 		}
       
   922 	anIndex=i;
       
   923 	return(ret);
       
   924 	}
       
   925 
       
   926 EXPORT_C TInt CArrayVarBase::FindIsq(const TAny *aPtr,TKeyArrayVar &aKey,TInt &anIndex) const
       
   927 //
       
   928 // Find using a binary search.
       
   929 //
       
   930 /**
       
   931 @internalComponent
       
   932 */
       
   933 	{
       
   934 
       
   935 	if (iCount==0)
       
   936 	    {
       
   937 	    anIndex=0;
       
   938 		return(-1);
       
   939 		}
       
   940 	aKey.SetPtr(aPtr);
       
   941 	SetKey(aKey);
       
   942 	return(User::BinarySearch(Count(),aKey,anIndex));
       
   943 	}
       
   944 
       
   945 EXPORT_C void CArrayVarBase::InsertL(TInt anIndex,const TAny *aPtr,TInt aLength)
       
   946 //
       
   947 // Insert a new record in the array.
       
   948 //
       
   949 /**
       
   950 @internalComponent
       
   951 */
       
   952 	{
       
   953 
       
   954 	TAny *pV=ExpandL(anIndex,aLength);
       
   955     Mem::Copy(pV,aPtr,aLength);
       
   956 	}
       
   957 
       
   958 EXPORT_C TInt CArrayVarBase::InsertIsqL(const TAny *aPtr,TInt aLength,TKeyArrayVar &aKey)
       
   959 //
       
   960 // Insert in sequence, no duplicates allowed.
       
   961 //
       
   962 /**
       
   963 @internalComponent
       
   964 */
       
   965 	{
       
   966 
       
   967 	TInt i=0;
       
   968 	TInt r=FindIsq(aPtr,aKey,i);
       
   969 	if (r==0) // a duplicate, leave
       
   970 		User::Leave(KErrAlreadyExists);
       
   971 	InsertL(i,aPtr,aLength);
       
   972 	return(i);
       
   973 	}
       
   974 
       
   975 EXPORT_C TInt CArrayVarBase::InsertIsqAllowDuplicatesL(const TAny *aPtr,TInt aLength,TKeyArrayVar &aKey)
       
   976 //
       
   977 // Insert in sequence, allow duplicates.
       
   978 //
       
   979 /**
       
   980 @internalComponent
       
   981 */
       
   982 	{
       
   983 
       
   984 	TInt i=0;
       
   985 	TInt r=FindIsq(aPtr,aKey,i);
       
   986 	if (r==0) // a duplicate, insert after
       
   987 		++i;
       
   988 	InsertL(i,aPtr,aLength);
       
   989 	return(i);
       
   990 	}
       
   991 
       
   992 EXPORT_C void CArrayVarBase::SetKey(TKeyArrayVar &aKey) const
       
   993 //
       
   994 // Set the key data.
       
   995 //
       
   996 /**
       
   997 @internalComponent
       
   998 */
       
   999 	{
       
  1000 
       
  1001 	aKey.Set(iBase);
       
  1002 	}
       
  1003 
       
  1004 EXPORT_C TInt CArrayVarBase::CountR(const CBase *aPtr)
       
  1005 //
       
  1006 // Return the number of items in the array.
       
  1007 //
       
  1008 /**
       
  1009 @internalComponent
       
  1010 */
       
  1011 	{
       
  1012 
       
  1013 	return(((CArrayVarBase *)aPtr)->Count());
       
  1014 	}
       
  1015 
       
  1016 EXPORT_C const TAny *CArrayVarBase::AtR(const CBase *aPtr,TInt anIndex)
       
  1017 //
       
  1018 // Return the address of an item in the array.
       
  1019 //
       
  1020 /**
       
  1021 @internalComponent
       
  1022 */
       
  1023 	{
       
  1024 
       
  1025 	return(((CArrayVarBase *)aPtr)->At(anIndex));
       
  1026 	}
       
  1027 
       
  1028 EXPORT_C CArrayPakBase::CArrayPakBase(TBufRep aRep,TInt aGranularity)
       
  1029 //
       
  1030 // Constructor
       
  1031 //
       
  1032 /**
       
  1033 @internalComponent
       
  1034 */
       
  1035 	{
       
  1036 
       
  1037 	__ASSERT_ALWAYS(aGranularity>0,Panic(EArrayPakInvalidGranularity));
       
  1038 //	iCount=0;
       
  1039 //	iBase=NULL;
       
  1040 	iGranularity=aGranularity;
       
  1041 	iCreateRep=aRep;
       
  1042 	}
       
  1043 
       
  1044 EXPORT_C CArrayPakBase::~CArrayPakBase()
       
  1045 /**
       
  1046 Destructor.
       
  1047 
       
  1048 Frees all resources owned by the object, prior to its destruction.
       
  1049 */
       
  1050 	{
       
  1051 
       
  1052 	if (iBase)
       
  1053 		{
       
  1054 		Reset();
       
  1055 		delete iBase;
       
  1056 		}
       
  1057 	}
       
  1058 
       
  1059 EXPORT_C TInt CArrayPakBase::Length(TInt anIndex) const
       
  1060 /**
       
  1061 Gets the length of the specified element.
       
  1062 
       
  1063 @param anIndex The position of the element within the array. The position 
       
  1064                is relative to zero, (i.e. the first element in the array is
       
  1065                at position 0). 
       
  1066 
       
  1067 @return The length of the element at position anIndex.
       
  1068 
       
  1069 @panic E32USER-CBase 21, if anIndex is negative or is greater than the number
       
  1070        of elements currently in the array.
       
  1071 */
       
  1072 	{
       
  1073 
       
  1074 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
       
  1075 	return(*((TInt *)iBase->Ptr(GetOffset(anIndex)).Ptr()));
       
  1076 	}
       
  1077 
       
  1078 EXPORT_C void CArrayPakBase::Compress()
       
  1079 /**
       
  1080 Removes excess space from the array buffer.
       
  1081 
       
  1082 The effect is to reduce the memory allocated to the array buffer so that it
       
  1083 is just sufficient to contain the elements of the array.
       
  1084 
       
  1085 If the array is empty, then the memory allocated to the array buffer is freed.
       
  1086 */
       
  1087 	{
       
  1088 
       
  1089 	if (iBase)
       
  1090 		iBase->Compress();
       
  1091 	}
       
  1092 
       
  1093 EXPORT_C void CArrayPakBase::Reset()
       
  1094 /**
       
  1095 Deletes all elements from the array and frees the memory allocated to the array 
       
  1096 buffer.
       
  1097 */
       
  1098 	{
       
  1099 
       
  1100 	Delete(0,Count());
       
  1101 	}
       
  1102 
       
  1103 EXPORT_C void CArrayPakBase::SortL(TKeyArrayVar &aKey)
       
  1104 //
       
  1105 // Builds a transient CArrayVarFlat array, sorts it
       
  1106 // and then copies it back to the original array.
       
  1107 //
       
  1108 /**
       
  1109 Sorts the elements of the array into key sequence.
       
  1110 
       
  1111 Note that the function requires a TKeyArrayVar key object because SortL()
       
  1112 creates a temporary CArrayVarFlat array in its implementation and uses that array's 
       
  1113 Sort() member function.
       
  1114 
       
  1115 @param aKey The key object defining the properties of the key.
       
  1116 
       
  1117 @see CArrayVarFlat
       
  1118 */
       
  1119 	{
       
  1120 
       
  1121 	if (iCount==0)
       
  1122 		return;
       
  1123 //
       
  1124 // First build a variable length flat array.
       
  1125 //
       
  1126 	CArrayVarFlat<TAny> *pVarFlat=NULL;
       
  1127 	TRAPD(r,BuildVarArrayL(pVarFlat))
       
  1128 	if (r==KErrNone)
       
  1129 		{
       
  1130 //
       
  1131 // Now sort it.
       
  1132 //
       
  1133 		r=pVarFlat->Sort(aKey);
       
  1134 		if (r==KErrNone)
       
  1135 			{
       
  1136 			//
       
  1137 			// Delete the records and copy back from pVarFlat.
       
  1138 			//
       
  1139  			Reset(); // Deletes the records but leaves the memory
       
  1140 			TInt tCount=pVarFlat->Count();
       
  1141 			for (TInt anIndex=0;anIndex<tCount;anIndex++)
       
  1142 	 			{
       
  1143 				TInt lenData=pVarFlat->Length(anIndex);
       
  1144 				TAny *pdata=pVarFlat->At(anIndex);
       
  1145 				TRAP(r,InsertL(anIndex,pdata,lenData));
       
  1146 				if (r!=KErrNone)
       
  1147 					break;
       
  1148 				}
       
  1149 			}
       
  1150 		}
       
  1151 	delete pVarFlat;
       
  1152 	User::LeaveIfError(r);
       
  1153 	}
       
  1154 
       
  1155 EXPORT_C TAny *CArrayPakBase::At(TInt anIndex) const
       
  1156 //
       
  1157 // TAny points to the data associated with the record with anIndex.
       
  1158 //
       
  1159 /**
       
  1160 @internalComponent
       
  1161 */
       
  1162 	{
       
  1163 
       
  1164 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
       
  1165 	TInt *pR=(TInt *)iBase->Ptr(GetOffset(anIndex)).Ptr();
       
  1166  	return((TAny *)(pR+1));
       
  1167 	}
       
  1168 
       
  1169 EXPORT_C void CArrayPakBase::Delete(TInt anIndex)
       
  1170 /**
       
  1171 Removes a single element from the array.
       
  1172 
       
  1173 Deleting elements from the array does not cause the array buffer to be
       
  1174 automatically compressed. Call CArrayPakBase::Compress() to return excess
       
  1175 space to the heap.
       
  1176 
       
  1177 @param anIndex The position within the array of the element to delete, relative 
       
  1178                to zero.
       
  1179 @panic E32USER-CBase 21, if anIndex is negative or is greater than the 
       
  1180        number of elements currently in the array.
       
  1181        
       
  1182 @see CArrayPakBase::Compress
       
  1183 */
       
  1184 	{
       
  1185 
       
  1186 	Delete(anIndex,1);
       
  1187 	}
       
  1188 
       
  1189 EXPORT_C void CArrayPakBase::Delete(TInt anIndex,TInt aCount)
       
  1190 /**
       
  1191 Removes one or more contiguous elements from the array, starting at a specific 
       
  1192 position.
       
  1193 
       
  1194 Deleting elements from the array does not cause the array buffer to be
       
  1195 automatically compressed. Call CArrayPakBase::Compress() to return excess
       
  1196 space to the heap.
       
  1197 
       
  1198 @param anIndex The position within the array from where deletion of elements 
       
  1199                is to start, relative to zero. 
       
  1200  
       
  1201 @param aCount  The number of elements to be deleted from the array.
       
  1202 
       
  1203 @panic E32USER-CBase 21, if anIndex is negative or greater than the number of
       
  1204        elements currently in the array.
       
  1205 @panic E32USER-CBase 26, if aCount is negative.
       
  1206 
       
  1207 @see CArrayPakBase::Compress
       
  1208 */
       
  1209 	{
       
  1210 
       
  1211 	if (aCount==0)
       
  1212 		return;
       
  1213 	__ASSERT_ALWAYS(aCount>0,Panic(EArrayCountNegative5));
       
  1214 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<iCount,Panic(EArrayIndexOutOfRange));
       
  1215 	TInt end=anIndex+aCount;
       
  1216 	__ASSERT_ALWAYS(end<=iCount,Panic(EArrayCountTooBig));
       
  1217 	TInt totalToDelete=0;
       
  1218 	TInt firstRecOffset=0;
       
  1219 	for (TInt i=anIndex;i<end;i++)
       
  1220 		{
       
  1221 		TInt offset=GetOffset(i);
       
  1222 		if (i==anIndex)
       
  1223 			{
       
  1224 			firstRecOffset=offset;
       
  1225 			iCacheIndex=i;
       
  1226 			iCacheOffset=offset;
       
  1227 			}
       
  1228 		TAny *pRecord=(TAny *)iBase->Ptr(offset).Ptr();
       
  1229 		TInt lenData=(*(TInt *)pRecord);
       
  1230 		totalToDelete+=Align4(lenData)+sizeof(TUint);
       
  1231 		}
       
  1232 	iBase->Delete(firstRecOffset,totalToDelete);
       
  1233 	iCount-=aCount;
       
  1234 	}
       
  1235 
       
  1236 EXPORT_C TAny *CArrayPakBase::ExpandL(TInt anIndex,TInt aLength)
       
  1237 //
       
  1238 // Expand the array at anIndex.
       
  1239 //
       
  1240 /**
       
  1241 @internalComponent
       
  1242 */
       
  1243 	{
       
  1244 
       
  1245 	if (iBase==NULL)
       
  1246 		iBase=(*iCreateRep)(iGranularity);
       
  1247 	__ASSERT_ALWAYS(aLength>=0,Panic(EArrayLengthNegative));
       
  1248 	__ASSERT_ALWAYS(anIndex>=0 && anIndex<=iCount,Panic(EArrayIndexOutOfRange));
       
  1249 	TInt offset=GetOffset(anIndex);
       
  1250 	iCacheIndex=anIndex;
       
  1251 	iCacheOffset=offset;
       
  1252 	iBase->ExpandL(offset,Align4(aLength+sizeof(TInt)));
       
  1253 	TInt *pR=(TInt *)iBase->Ptr(offset).Ptr();
       
  1254 	*pR=aLength;
       
  1255 	iCount++;
       
  1256  	return((TAny *)(pR+1));
       
  1257 	}
       
  1258 
       
  1259 EXPORT_C TInt CArrayPakBase::Find(const TAny *aPtr,TKeyArrayPak &aKey,TInt &anIndex) const
       
  1260 //
       
  1261 // Find using a sequential search.
       
  1262 //
       
  1263 /**
       
  1264 @internalComponent
       
  1265 */
       
  1266 	{
       
  1267 
       
  1268 	if (iCount==0)
       
  1269 	    {
       
  1270 	    anIndex=0;
       
  1271 		return(-1);
       
  1272 		}
       
  1273 	aKey.SetPtr(aPtr);
       
  1274 	SetKey(aKey);
       
  1275 	TInt ret=(-1);
       
  1276 	TInt i=0;
       
  1277 	while (i<Count())
       
  1278 		{
       
  1279 		TInt j=aKey.Compare(i,KIndexPtr);
       
  1280 		if (j==0)
       
  1281 			{
       
  1282 			ret=j;
       
  1283 			break;
       
  1284 			}
       
  1285 		i++;
       
  1286 		}
       
  1287 	anIndex=i;
       
  1288 	return(ret);
       
  1289 	}
       
  1290 
       
  1291 EXPORT_C TInt CArrayPakBase::FindIsq(const TAny *aPtr,TKeyArrayPak &aKey,TInt &anIndex) const
       
  1292 //
       
  1293 // Find using a binary search.
       
  1294 //
       
  1295 /**
       
  1296 @internalComponent
       
  1297 */
       
  1298 	{
       
  1299 
       
  1300 	if (iCount==0)
       
  1301 	    {
       
  1302 	    anIndex=0;
       
  1303 		return(-1);
       
  1304 		}
       
  1305 	aKey.SetPtr(aPtr);
       
  1306 	SetKey(aKey);
       
  1307 	return(User::BinarySearch(Count(),aKey,anIndex));
       
  1308 	}
       
  1309 
       
  1310 EXPORT_C void CArrayPakBase::InsertL(TInt anIndex,const TAny *aPtr,TInt aLength)
       
  1311 //
       
  1312 // Inserts a record at index anIndex.
       
  1313 //
       
  1314 /**
       
  1315 @internalComponent
       
  1316 */
       
  1317 	{
       
  1318 
       
  1319 	TAny *pV=ExpandL(anIndex,aLength);
       
  1320     Mem::Copy(pV,aPtr,aLength);
       
  1321 	}
       
  1322 
       
  1323 EXPORT_C TInt CArrayPakBase::InsertIsqL(const TAny *aPtr,TInt aLength,TKeyArrayPak &aKey)
       
  1324 //
       
  1325 // Insert in sequence, no duplicates allowed.
       
  1326 //
       
  1327 /**
       
  1328 @internalComponent
       
  1329 */
       
  1330 	{
       
  1331 
       
  1332 	TInt i=0;
       
  1333 	TInt r=FindIsq(aPtr,aKey,i);
       
  1334 	if (r==0) // a duplicate, leave
       
  1335 		User::Leave(KErrAlreadyExists);
       
  1336 	InsertL(i,aPtr,aLength);
       
  1337 	return(i);
       
  1338 	}
       
  1339 
       
  1340 EXPORT_C TInt CArrayPakBase::InsertIsqAllowDuplicatesL(const TAny *aPtr,TInt aLength,TKeyArrayPak &aKey)
       
  1341 //
       
  1342 // Insert in sequence, allow duplicates.
       
  1343 //
       
  1344 /**
       
  1345 @internalComponent
       
  1346 */
       
  1347 	{
       
  1348 
       
  1349 	TInt i=0;
       
  1350 	TInt r=FindIsq(aPtr,aKey,i);
       
  1351 	if (r==0) // a duplicate, insert after
       
  1352 		++i;
       
  1353 	InsertL(i,aPtr,aLength);
       
  1354 	return(i);
       
  1355 	}
       
  1356 
       
  1357 EXPORT_C void CArrayPakBase::SetKey(TKeyArrayPak &aKey) const
       
  1358 //
       
  1359 // Set the key data.
       
  1360 //
       
  1361 /**
       
  1362 @internalComponent
       
  1363 */
       
  1364 	{
       
  1365 
       
  1366 	aKey.Set(iBase);
       
  1367 	}
       
  1368 
       
  1369 EXPORT_C TInt CArrayPakBase::GetOffset(TInt anIndex) const
       
  1370 //
       
  1371 // Return the offset into the buffer of the record with index anIndex;
       
  1372 //
       
  1373 /**
       
  1374 @internalComponent
       
  1375 */
       
  1376 	{
       
  1377 
       
  1378 	TInt offset=0;
       
  1379  	TInt curIndex=0;
       
  1380 	if (iCacheIndex<=anIndex)
       
  1381 		{
       
  1382 		curIndex=iCacheIndex;
       
  1383 		offset=iCacheOffset;
       
  1384 		}
       
  1385 	TAny *pRecord=(TAny *)iBase->Ptr(offset).Ptr();
       
  1386 	while (curIndex<anIndex)
       
  1387 		{
       
  1388 		TInt lenData=(*(TInt *)pRecord);
       
  1389 		offset+=Align4(lenData)+sizeof(TUint);
       
  1390 		pRecord=(TAny *)iBase->Ptr(offset).Ptr();
       
  1391 		curIndex++;
       
  1392 		}
       
  1393 	(TInt &)iCacheIndex=anIndex;
       
  1394 	(TInt &)iCacheOffset=offset;
       
  1395  	return(offset);
       
  1396 	}
       
  1397 
       
  1398 EXPORT_C void CArrayPakBase::BuildVarArrayL(CArrayVarFlat<TAny> * &aVarFlat)
       
  1399 //
       
  1400 // Make a copy of the current array as a CArrayVarFlat
       
  1401 //
       
  1402 /**
       
  1403 @internalComponent
       
  1404 */
       
  1405 	{
       
  1406 
       
  1407 	aVarFlat=new(ELeave) CArrayVarFlat<TAny>(iGranularity);
       
  1408 	for (TInt anIndex=0;anIndex<iCount;anIndex++)
       
  1409 		{
       
  1410 		TInt offset=GetOffset(anIndex);
       
  1411 		TAny *pRecord=(TAny *)iBase->Ptr(offset).Ptr();
       
  1412 		TInt lengthData=(*(TInt *)pRecord);
       
  1413 		TAny *pData=(TAny *)((TInt *)pRecord+1);
       
  1414 		aVarFlat->InsertL(anIndex,pData,lengthData);
       
  1415 		}
       
  1416 	}
       
  1417 
       
  1418 EXPORT_C TInt CArrayPakBase::CountR(const CBase *aPtr)
       
  1419 //
       
  1420 // Return the number of items in the array.
       
  1421 //
       
  1422 /**
       
  1423 @internalComponent
       
  1424 */
       
  1425 	{
       
  1426 
       
  1427 	return(((CArrayPakBase *)aPtr)->Count());
       
  1428 	}
       
  1429 
       
  1430 EXPORT_C const TAny *CArrayPakBase::AtR(const CBase *aPtr,TInt anIndex)
       
  1431 //
       
  1432 // Return the address of an item in the array.
       
  1433 //
       
  1434 /**
       
  1435 @internalComponent
       
  1436 */
       
  1437 	{
       
  1438 
       
  1439 	return(((CArrayPakBase *)aPtr)->At(anIndex));
       
  1440 	}
       
  1441 
       
  1442 EXPORT_C CArrayFixFlat<TInt>::CArrayFixFlat(TInt aGranularity)
       
  1443 	: CArrayFix<TInt>((TBufRep)CBufFlat::NewL,aGranularity)
       
  1444 /**
       
  1445 Constructs the array, with the specified granularity, to contain elements of 
       
  1446 TInt type.
       
  1447 	
       
  1448 Note that no memory is allocated to the array buffer by this C++ constructor.
       
  1449 	
       
  1450 @param aGranularity The granularity of the array. 
       
  1451 
       
  1452 @panic E32USER-CBase 18 if aGranularity is not positive.
       
  1453 */
       
  1454 	{}
       
  1455 
       
  1456 EXPORT_C CArrayFixFlat<TInt>::~CArrayFixFlat()
       
  1457 /**
       
  1458 Destructor.
       
  1459 */
       
  1460 	{}
       
  1461 
       
  1462 EXPORT_C CArrayFixFlat<TUid>::CArrayFixFlat(TInt aGranularity)
       
  1463 	: CArrayFix<TUid>((TBufRep)CBufFlat::NewL,aGranularity)
       
  1464 /**
       
  1465 Constructs the array, with the specified granularity, to contain elements of 
       
  1466 TUid type.
       
  1467 
       
  1468 Note that no memory is allocated to the array buffer by this C++ constructor.
       
  1469 	
       
  1470 @param aGranularity The granularity of the array.
       
  1471 
       
  1472 @panic E32USER-CBase 18 if aGranularity is not positive.
       
  1473 */
       
  1474 	{}
       
  1475 
       
  1476 EXPORT_C CArrayFixFlat<TUid>::~CArrayFixFlat()
       
  1477 /**
       
  1478 Destructor.
       
  1479 */
       
  1480 	{}