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