os/kernelhwsrv/kernel/eka/common/array.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1998-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\common\array.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "common.h"
sl@0
    19
#ifdef __KERNEL_MODE__
sl@0
    20
#include <kernel/kernel.h>
sl@0
    21
#endif
sl@0
    22
sl@0
    23
const TInt KDefaultPtrArrayGranularity		=8;
sl@0
    24
const TInt KPtrArrayMaxGranularity			=0x10000000;
sl@0
    25
const TInt KDefaultSimpleArrayGranularity	=8;
sl@0
    26
const TInt KSimpleArrayMaxGranularity		=0x10000000;
sl@0
    27
const TInt KSimpleArrayMaxEntrySize			=640;	// allow room for a unicode TFullName
sl@0
    28
const TInt KMaxArrayGrowBy					=65535;
sl@0
    29
const TInt KMinArrayFactor					=257;
sl@0
    30
const TInt KMaxArrayFactor					=32767;
sl@0
    31
sl@0
    32
EXPORT_C RPointerArrayBase::RPointerArrayBase()
sl@0
    33
	: iCount(0), iEntries(NULL), iAllocated(0), iGranularity(KDefaultPtrArrayGranularity), iSpare1(0), iSpare2(0)
sl@0
    34
	{}
sl@0
    35
sl@0
    36
EXPORT_C RPointerArrayBase::RPointerArrayBase(TInt aGranularity)
sl@0
    37
	: iCount(0), iEntries(NULL), iAllocated(0), iGranularity(aGranularity), iSpare1(0), iSpare2(0)
sl@0
    38
	{
sl@0
    39
	__ASSERT_ALWAYS(aGranularity>0 && aGranularity<=KPtrArrayMaxGranularity,
sl@0
    40
		Panic(EBadArrayGranularity));
sl@0
    41
	}
sl@0
    42
sl@0
    43
EXPORT_C RPointerArrayBase::RPointerArrayBase(TInt aMinGrowBy, TInt aFactor)
sl@0
    44
	: iCount(0), iEntries(NULL), iAllocated(0), iSpare1(0), iSpare2(0)
sl@0
    45
	{
sl@0
    46
	__ASSERT_ALWAYS(aMinGrowBy>0 && aMinGrowBy<=KMaxArrayGrowBy, Panic(EBadArrayMinGrowBy));
sl@0
    47
	__ASSERT_ALWAYS(aFactor>=KMinArrayFactor && aFactor<=KMaxArrayFactor, Panic(EBadArrayFactor));
sl@0
    48
	iGranularity = aMinGrowBy | (aFactor << 16) | 0x80000000;
sl@0
    49
	}
sl@0
    50
sl@0
    51
#ifndef __KERNEL_MODE__
sl@0
    52
EXPORT_C RPointerArrayBase::RPointerArrayBase(TAny** aEntries, TInt aCount)
sl@0
    53
	: iCount(aCount), iEntries(aEntries), iAllocated(aCount), iGranularity(aCount), iSpare1(0), iSpare2(0)
sl@0
    54
	{
sl@0
    55
	__ASSERT_ALWAYS(aCount>0,Panic(EBadArrayCount));
sl@0
    56
	}
sl@0
    57
#endif
sl@0
    58
sl@0
    59
EXPORT_C void RPointerArrayBase::Close()
sl@0
    60
	{
sl@0
    61
	iCount=0;
sl@0
    62
	STD_CLASS::Free(iEntries);
sl@0
    63
	iEntries=NULL;
sl@0
    64
	iAllocated=0;
sl@0
    65
	}
sl@0
    66
sl@0
    67
EXPORT_C TInt RPointerArrayBase::Count() const
sl@0
    68
	{
sl@0
    69
	return iCount;
sl@0
    70
	}
sl@0
    71
sl@0
    72
#ifndef __ARRAY_MACHINE_CODED__
sl@0
    73
EXPORT_C TAny*& RPointerArrayBase::At(TInt anIndex) const
sl@0
    74
	{
sl@0
    75
	__ASSERT_ALWAYS((anIndex>=0 && anIndex<iCount),Panic(EBadArrayIndex));
sl@0
    76
	return iEntries[anIndex];
sl@0
    77
	}
sl@0
    78
#else
sl@0
    79
GLDEF_C void PanicBadArrayIndex()
sl@0
    80
	{
sl@0
    81
	Panic(EBadArrayIndex);
sl@0
    82
	}
sl@0
    83
#endif
sl@0
    84
sl@0
    85
TInt CalculateArraySizeAfterGrow(TInt aOrigSize, TInt aGranularity, TInt aLimit)
sl@0
    86
	{
sl@0
    87
	if (aGranularity >= 0)
sl@0
    88
		{
sl@0
    89
		if (aOrigSize > aLimit - aGranularity)
sl@0
    90
			return KErrNoMemory;	// array can't be >2GB
sl@0
    91
		return aOrigSize + aGranularity;
sl@0
    92
		}
sl@0
    93
	TUint minStep = (TUint)(aGranularity & 65535);
sl@0
    94
	TUint factor = TUint(aGranularity & 0x7fff0000) >> 16;
sl@0
    95
	Uint64 na64 = aOrigSize;
sl@0
    96
	na64 *= (Uint64)factor;
sl@0
    97
	na64 += 128;
sl@0
    98
	na64 >>= 8;
sl@0
    99
	Uint64 min_na64 = (Uint64)aOrigSize + (Uint64)minStep;
sl@0
   100
	if (min_na64 > na64)
sl@0
   101
		na64 = min_na64;
sl@0
   102
	if (na64 > (Uint64)aLimit)
sl@0
   103
		return KErrNoMemory;	// array can't be >2GB
sl@0
   104
	return (TInt)na64;
sl@0
   105
	}
sl@0
   106
sl@0
   107
TInt CalculateArraySizeAfterShrink(TInt aOrigSize, TInt aGranularity, TInt aUsed)
sl@0
   108
	{
sl@0
   109
	TInt step = aGranularity;
sl@0
   110
	if (step < 0)
sl@0
   111
		step &= 65535;
sl@0
   112
	if (aOrigSize - aUsed < step)
sl@0
   113
		return aOrigSize;
sl@0
   114
	aUsed += step - 1;
sl@0
   115
	aUsed /= step;
sl@0
   116
	aUsed *= step;
sl@0
   117
	return aUsed;
sl@0
   118
	}
sl@0
   119
sl@0
   120
TInt RPointerArrayBase::Grow()
sl@0
   121
	{
sl@0
   122
	TInt newAlloc = CalculateArraySizeAfterGrow(iAllocated, iGranularity, KMaxTInt >> 2);
sl@0
   123
	if (newAlloc < 0)
sl@0
   124
		return newAlloc;
sl@0
   125
	TAny** pA = (TAny**)STD_CLASS::ReAlloc(iEntries, newAlloc*sizeof(TAny*));
sl@0
   126
	if (!pA)
sl@0
   127
		return KErrNoMemory;
sl@0
   128
	iEntries = pA;
sl@0
   129
	iAllocated = newAlloc;
sl@0
   130
	return KErrNone;
sl@0
   131
	}
sl@0
   132
sl@0
   133
#ifndef __ARRAY_MACHINE_CODED__
sl@0
   134
EXPORT_C TInt RPointerArrayBase::Append(const TAny* anEntry)
sl@0
   135
	{
sl@0
   136
	if (iCount==iAllocated)
sl@0
   137
		{
sl@0
   138
		TInt r=Grow();
sl@0
   139
		if (r!=KErrNone)
sl@0
   140
			return r;
sl@0
   141
		}
sl@0
   142
	iEntries[iCount++]=(TAny*)anEntry;
sl@0
   143
	return KErrNone;
sl@0
   144
	}
sl@0
   145
#endif
sl@0
   146
sl@0
   147
EXPORT_C TInt RPointerArrayBase::Insert(const TAny* anEntry, TInt aPos)
sl@0
   148
	{
sl@0
   149
	__ASSERT_ALWAYS((aPos>=0 && aPos<=iCount),Panic(EBadArrayPosition));
sl@0
   150
	if (iCount==iAllocated)
sl@0
   151
		{
sl@0
   152
		TInt r=Grow();
sl@0
   153
		if (r!=KErrNone)
sl@0
   154
			return r;
sl@0
   155
		}
sl@0
   156
	TInt entries=iCount-aPos;
sl@0
   157
	if (entries!=0)
sl@0
   158
		wordmove(iEntries+aPos+1,iEntries+aPos,entries*sizeof(TAny*));
sl@0
   159
	iCount++;
sl@0
   160
	iEntries[aPos]=(TAny*)anEntry;
sl@0
   161
	return KErrNone;
sl@0
   162
	}
sl@0
   163
sl@0
   164
EXPORT_C void RPointerArrayBase::Remove(TInt anIndex)
sl@0
   165
	{
sl@0
   166
	__ASSERT_ALWAYS((anIndex>=0 && anIndex<iCount),Panic(EBadArrayIndex));
sl@0
   167
	TInt entries=iCount-anIndex-1;
sl@0
   168
	if (entries!=0)
sl@0
   169
		wordmove(iEntries+anIndex,iEntries+anIndex+1,entries*sizeof(TAny*));
sl@0
   170
	iCount--;
sl@0
   171
	}
sl@0
   172
sl@0
   173
EXPORT_C void RPointerArrayBase::Compress()
sl@0
   174
	{
sl@0
   175
	if (iCount)
sl@0
   176
		iEntries=(TAny**)STD_CLASS::ReAlloc(iEntries,iCount*sizeof(TAny*)); // can't fail
sl@0
   177
	else
sl@0
   178
		{
sl@0
   179
		STD_CLASS::Free(iEntries);
sl@0
   180
		iEntries=NULL;
sl@0
   181
		}
sl@0
   182
	iAllocated=iCount;
sl@0
   183
	}
sl@0
   184
sl@0
   185
#ifndef __KERNEL_MODE__
sl@0
   186
EXPORT_C void RPointerArrayBase::GranularCompress()
sl@0
   187
	{
sl@0
   188
	TInt newAlloc = CalculateArraySizeAfterShrink(iAllocated, iGranularity, iCount);
sl@0
   189
	if (newAlloc == iAllocated)
sl@0
   190
		return;
sl@0
   191
	if (newAlloc)
sl@0
   192
		iEntries=(TAny**)STD_CLASS::ReAlloc(iEntries,newAlloc*sizeof(TAny*)); // can't fail
sl@0
   193
	else
sl@0
   194
		{
sl@0
   195
		STD_CLASS::Free(iEntries);
sl@0
   196
		iEntries=NULL;
sl@0
   197
		}
sl@0
   198
	iAllocated=newAlloc;
sl@0
   199
	}
sl@0
   200
sl@0
   201
EXPORT_C TInt RPointerArrayBase::DoReserve(TInt aCount)
sl@0
   202
	{
sl@0
   203
	__ASSERT_ALWAYS(aCount>=0, Panic(EArrayBadReserveCount));
sl@0
   204
	if (aCount <= iAllocated)
sl@0
   205
		return KErrNone;	// if allocated space is already sufficient, nothing to do
sl@0
   206
sl@0
   207
	const TInt KLimit = TInt(0x80000000u / sizeof(TAny*));
sl@0
   208
	if (aCount >= KLimit)
sl@0
   209
		return KErrNoMemory;
sl@0
   210
sl@0
   211
	TAny** pA = (TAny**)STD_CLASS::ReAlloc(iEntries, aCount*sizeof(TAny*));
sl@0
   212
	if (!pA)
sl@0
   213
		return KErrNoMemory;
sl@0
   214
	iEntries = pA;
sl@0
   215
	iAllocated = aCount;
sl@0
   216
	return KErrNone;
sl@0
   217
	}
sl@0
   218
#endif
sl@0
   219
sl@0
   220
EXPORT_C void RPointerArrayBase::Reset()
sl@0
   221
	{
sl@0
   222
	iCount=0;
sl@0
   223
	STD_CLASS::Free(iEntries);
sl@0
   224
	iEntries=NULL;
sl@0
   225
	iAllocated=0;
sl@0
   226
	}
sl@0
   227
sl@0
   228
EXPORT_C TInt RPointerArrayBase::BinarySearch(const TAny* anEntry, TInt& anIndex, TGeneralLinearOrder anOrder) const
sl@0
   229
	{
sl@0
   230
	return BinarySearch(anEntry, anIndex, anOrder, EArrayFindMode_Any);
sl@0
   231
	}
sl@0
   232
sl@0
   233
#ifndef __ARRAY_MACHINE_CODED__
sl@0
   234
EXPORT_C TInt RPointerArrayBase::Find(const TAny* anEntry) const
sl@0
   235
	{
sl@0
   236
	TInt i;
sl@0
   237
	for (i=0; i<iCount; i++)
sl@0
   238
		{
sl@0
   239
		if (iEntries[i]==anEntry)
sl@0
   240
			return i;
sl@0
   241
		}
sl@0
   242
	return KErrNotFound;
sl@0
   243
	}
sl@0
   244
sl@0
   245
EXPORT_C TInt RPointerArrayBase::Find(const TAny* anEntry, TGeneralIdentityRelation anIdentity) const
sl@0
   246
	{
sl@0
   247
	TInt i;
sl@0
   248
	for (i=0; i<iCount; i++)
sl@0
   249
		{
sl@0
   250
		if ((*anIdentity)(anEntry,iEntries[i]))
sl@0
   251
			return i;
sl@0
   252
		}
sl@0
   253
	return KErrNotFound;
sl@0
   254
	}
sl@0
   255
sl@0
   256
EXPORT_C TInt RPointerArrayBase::BinarySearchSigned(TInt anEntry, TInt& anIndex) const
sl@0
   257
	{
sl@0
   258
	return BinarySearchSigned(anEntry, anIndex, EArrayFindMode_Any);
sl@0
   259
	}
sl@0
   260
sl@0
   261
EXPORT_C TInt RPointerArrayBase::BinarySearchSigned(TInt anEntry, TInt& anIndex, TInt aMode) const
sl@0
   262
	{
sl@0
   263
	__ASSERT_DEBUG(TUint(aMode)<TUint(EArrayFindMode_Limit), Panic(EBadArrayFindMode));
sl@0
   264
	TInt l=0;
sl@0
   265
	TInt r=iCount;
sl@0
   266
	TInt ret = KErrNotFound;
sl@0
   267
	while(r>l)
sl@0
   268
		{
sl@0
   269
		TInt m=(l+r)>>1;
sl@0
   270
		TInt h=(TInt)iEntries[m];
sl@0
   271
		if (anEntry==h)
sl@0
   272
			{
sl@0
   273
			if (aMode == EArrayFindMode_Any)
sl@0
   274
				{
sl@0
   275
				anIndex=m;
sl@0
   276
				return KErrNone;
sl@0
   277
				}
sl@0
   278
			ret = KErrNone;
sl@0
   279
			if (aMode == EArrayFindMode_First)
sl@0
   280
				r=m;
sl@0
   281
			else
sl@0
   282
				l=m+1;
sl@0
   283
			}
sl@0
   284
		else if (anEntry>h)
sl@0
   285
			l=m+1;
sl@0
   286
		else
sl@0
   287
			r=m;
sl@0
   288
		}
sl@0
   289
	anIndex=r;
sl@0
   290
	return ret;
sl@0
   291
	}
sl@0
   292
sl@0
   293
EXPORT_C TInt RPointerArrayBase::BinarySearchUnsigned(TUint anEntry, TInt& anIndex) const
sl@0
   294
	{
sl@0
   295
	return BinarySearchUnsigned(anEntry, anIndex, EArrayFindMode_Any);
sl@0
   296
	}
sl@0
   297
sl@0
   298
EXPORT_C TInt RPointerArrayBase::BinarySearchUnsigned(TUint anEntry, TInt& anIndex, TInt aMode) const
sl@0
   299
	{
sl@0
   300
	__ASSERT_DEBUG(TUint(aMode)<TUint(EArrayFindMode_Limit), Panic(EBadArrayFindMode));
sl@0
   301
	TInt l=0;
sl@0
   302
	TInt r=iCount;
sl@0
   303
	TInt ret = KErrNotFound;
sl@0
   304
	while(r>l)
sl@0
   305
		{
sl@0
   306
		TUint m=(l+r)>>1;
sl@0
   307
		TUint h=(TUint)iEntries[m];
sl@0
   308
		if (anEntry==h)
sl@0
   309
			{
sl@0
   310
			if (aMode == EArrayFindMode_Any)
sl@0
   311
				{
sl@0
   312
				anIndex=m;
sl@0
   313
				return KErrNone;
sl@0
   314
				}
sl@0
   315
			ret = KErrNone;
sl@0
   316
			if (aMode == EArrayFindMode_First)
sl@0
   317
				r=m;
sl@0
   318
			else
sl@0
   319
				l=m+1;
sl@0
   320
			}
sl@0
   321
		else if (anEntry>h)
sl@0
   322
			l=m+1;
sl@0
   323
		else
sl@0
   324
			r=m;
sl@0
   325
		}
sl@0
   326
	anIndex=r;
sl@0
   327
	return ret;
sl@0
   328
	}
sl@0
   329
sl@0
   330
EXPORT_C TInt RPointerArrayBase::BinarySearch(const TAny* anEntry, TInt& anIndex, TGeneralLinearOrder anOrder, TInt aMode) const
sl@0
   331
	{
sl@0
   332
	__ASSERT_DEBUG(TUint(aMode)<TUint(EArrayFindMode_Limit), Panic(EBadArrayFindMode));
sl@0
   333
	TInt l=0;
sl@0
   334
	TInt r=iCount;
sl@0
   335
	TInt ret = KErrNotFound;
sl@0
   336
	while(r>l)
sl@0
   337
		{
sl@0
   338
		TInt m=(l+r)>>1;
sl@0
   339
		TInt k=(*anOrder)(anEntry,iEntries[m]);
sl@0
   340
		if (k==0)
sl@0
   341
			{
sl@0
   342
			if (aMode == EArrayFindMode_Any)
sl@0
   343
				{
sl@0
   344
				anIndex=m;
sl@0
   345
				return KErrNone;
sl@0
   346
				}
sl@0
   347
			ret = KErrNone;
sl@0
   348
			if (aMode == EArrayFindMode_First)
sl@0
   349
				r=m;
sl@0
   350
			else
sl@0
   351
				l=m+1;
sl@0
   352
			}
sl@0
   353
		else if (k>0)
sl@0
   354
			l=m+1;
sl@0
   355
		else
sl@0
   356
			r=m;
sl@0
   357
		}
sl@0
   358
	anIndex=r;
sl@0
   359
	return ret;
sl@0
   360
	}
sl@0
   361
sl@0
   362
EXPORT_C TInt RPointerArrayBase::FindIsqSigned(TInt anEntry) const
sl@0
   363
	{
sl@0
   364
	return FindIsqSigned(anEntry, EArrayFindMode_Any);
sl@0
   365
	}
sl@0
   366
sl@0
   367
EXPORT_C TInt RPointerArrayBase::FindIsqUnsigned(TUint anEntry) const
sl@0
   368
	{
sl@0
   369
	return FindIsqUnsigned(anEntry, EArrayFindMode_Any);
sl@0
   370
	}
sl@0
   371
sl@0
   372
EXPORT_C TInt RPointerArrayBase::FindIsq(const TAny* anEntry, TGeneralLinearOrder anOrder) const
sl@0
   373
	{
sl@0
   374
	return FindIsq(anEntry, anOrder, EArrayFindMode_Any);
sl@0
   375
	}
sl@0
   376
sl@0
   377
EXPORT_C TInt RPointerArrayBase::FindIsqSigned(TInt anEntry, TInt aMode) const
sl@0
   378
	{
sl@0
   379
	TInt i;
sl@0
   380
	TInt r=BinarySearchSigned(anEntry,i,aMode);
sl@0
   381
	return (r==KErrNone)?i:r;
sl@0
   382
	}
sl@0
   383
sl@0
   384
EXPORT_C TInt RPointerArrayBase::FindIsqUnsigned(TUint anEntry, TInt aMode) const
sl@0
   385
	{
sl@0
   386
	TInt i;
sl@0
   387
	TInt r=BinarySearchUnsigned(anEntry,i,aMode);
sl@0
   388
	return (r==KErrNone)?i:r;
sl@0
   389
	}
sl@0
   390
sl@0
   391
EXPORT_C TInt RPointerArrayBase::FindIsq(const TAny* anEntry, TGeneralLinearOrder anOrder, TInt aMode) const
sl@0
   392
	{
sl@0
   393
	TInt i;
sl@0
   394
	TInt r=BinarySearch(anEntry,i,anOrder,aMode);
sl@0
   395
	return (r==KErrNone)?i:r;
sl@0
   396
	}
sl@0
   397
#else
sl@0
   398
extern "C" void PanicBadArrayFindMode()
sl@0
   399
	{
sl@0
   400
	Panic(EBadArrayFindMode);
sl@0
   401
	}
sl@0
   402
#endif
sl@0
   403
sl@0
   404
sl@0
   405
EXPORT_C TInt RPointerArrayBase::FindReverse(const TAny* anEntry) const
sl@0
   406
	{
sl@0
   407
	TInt i=iCount;
sl@0
   408
	while (i--)
sl@0
   409
		{
sl@0
   410
		if (iEntries[i]==anEntry)
sl@0
   411
			return i;
sl@0
   412
		}
sl@0
   413
	return KErrNotFound;
sl@0
   414
	}
sl@0
   415
sl@0
   416
EXPORT_C TInt RPointerArrayBase::FindReverse(const TAny* anEntry, TGeneralIdentityRelation anIdentity) const
sl@0
   417
	{
sl@0
   418
	TInt i=iCount;
sl@0
   419
	while (i--)
sl@0
   420
		{
sl@0
   421
		if ((*anIdentity)(anEntry,iEntries[i]))
sl@0
   422
			return i;
sl@0
   423
		}
sl@0
   424
	return KErrNotFound;
sl@0
   425
	}
sl@0
   426
sl@0
   427
sl@0
   428
EXPORT_C TInt RPointerArrayBase::InsertIsqSigned(TInt anEntry, TBool aAllowRepeats)
sl@0
   429
	{
sl@0
   430
	TInt i;
sl@0
   431
	TInt mode = aAllowRepeats ? EArrayFindMode_Last : EArrayFindMode_Any;
sl@0
   432
	TInt r=BinarySearchSigned(anEntry,i,mode);
sl@0
   433
	if (r==KErrNotFound || aAllowRepeats)
sl@0
   434
		return Insert((const TAny*)anEntry,i);
sl@0
   435
	return KErrAlreadyExists;
sl@0
   436
	}
sl@0
   437
sl@0
   438
EXPORT_C TInt RPointerArrayBase::InsertIsqUnsigned(TUint anEntry, TBool aAllowRepeats)
sl@0
   439
	{
sl@0
   440
	TInt i;
sl@0
   441
	TInt mode = aAllowRepeats ? EArrayFindMode_Last : EArrayFindMode_Any;
sl@0
   442
	TInt r=BinarySearchUnsigned(anEntry,i,mode);
sl@0
   443
	if (r==KErrNotFound || aAllowRepeats)
sl@0
   444
		return Insert((const TAny*)anEntry,i);
sl@0
   445
	return KErrAlreadyExists;
sl@0
   446
	}
sl@0
   447
sl@0
   448
EXPORT_C TInt RPointerArrayBase::InsertIsq(const TAny* anEntry, TGeneralLinearOrder anOrder, TBool aAllowRepeats)
sl@0
   449
	{
sl@0
   450
	TInt i;
sl@0
   451
	TInt mode = aAllowRepeats ? EArrayFindMode_Last : EArrayFindMode_Any;
sl@0
   452
	TInt r=BinarySearch(anEntry,i,anOrder,mode);
sl@0
   453
	if (r==KErrNotFound || aAllowRepeats)
sl@0
   454
		return Insert((const TAny*)anEntry,i);
sl@0
   455
	return KErrAlreadyExists;
sl@0
   456
	}
sl@0
   457
sl@0
   458
#ifndef __ARRAY_MACHINE_CODED__
sl@0
   459
void HeapSortUnsigned(TUint* aEntries,TInt aCount)
sl@0
   460
	{
sl@0
   461
	TInt ss = aCount;
sl@0
   462
	if (ss>1)
sl@0
   463
		{
sl@0
   464
		TInt sh = ss>>1;
sl@0
   465
		FOREVER
sl@0
   466
			{
sl@0
   467
			TUint si;
sl@0
   468
			if (sh!=0)
sl@0
   469
				{
sl@0
   470
				--sh;
sl@0
   471
				si = aEntries[sh];
sl@0
   472
				}
sl@0
   473
			else
sl@0
   474
				{
sl@0
   475
				--ss;
sl@0
   476
				si = aEntries[ss];
sl@0
   477
				aEntries[ss]=aEntries[0];
sl@0
   478
				if (ss==1)
sl@0
   479
					{
sl@0
   480
					aEntries[0]=si;
sl@0
   481
					break;
sl@0
   482
					}
sl@0
   483
				}
sl@0
   484
			TInt ii = sh;
sl@0
   485
			TInt jj = sh;
sl@0
   486
			FOREVER
sl@0
   487
				{
sl@0
   488
				jj = (jj+1)<<1;
sl@0
   489
				if (jj>=ss || TUint(aEntries[jj-1])>TUint(aEntries[jj]) )
sl@0
   490
					--jj;
sl@0
   491
				if (jj>=ss || TUint(aEntries[jj])<=si)
sl@0
   492
					break;
sl@0
   493
				aEntries[ii]=aEntries[jj];
sl@0
   494
				ii = jj;
sl@0
   495
				}
sl@0
   496
			aEntries[ii]=si;
sl@0
   497
			}
sl@0
   498
		}
sl@0
   499
	}
sl@0
   500
#endif // !__ARRAY_MACHINE_CODED__
sl@0
   501
sl@0
   502
sl@0
   503
#ifndef __KERNEL_MODE__
sl@0
   504
#ifndef __ARRAY_MACHINE_CODED__
sl@0
   505
EXPORT_C void RPointerArrayBase::HeapSortSigned()
sl@0
   506
	{
sl@0
   507
	TInt ss = iCount;
sl@0
   508
	if (ss>1)
sl@0
   509
		{
sl@0
   510
		TInt sh = ss>>1;
sl@0
   511
		FOREVER
sl@0
   512
			{
sl@0
   513
			TInt si;
sl@0
   514
			if (sh!=0)
sl@0
   515
				{
sl@0
   516
				--sh;
sl@0
   517
				si = (TInt)iEntries[sh];
sl@0
   518
				}
sl@0
   519
			else
sl@0
   520
				{
sl@0
   521
				--ss;
sl@0
   522
				si = (TInt)iEntries[ss];
sl@0
   523
				iEntries[ss]=iEntries[0];
sl@0
   524
				if (ss==1)
sl@0
   525
					{
sl@0
   526
					iEntries[0]=(TAny*)si;
sl@0
   527
					break;
sl@0
   528
					}
sl@0
   529
				}
sl@0
   530
			TInt ii = sh;
sl@0
   531
			TInt jj = sh;
sl@0
   532
			FOREVER
sl@0
   533
				{
sl@0
   534
				jj = (jj+1)<<1;
sl@0
   535
				if (jj>=ss || TInt(iEntries[jj-1])>TInt(iEntries[jj]) )
sl@0
   536
					--jj;
sl@0
   537
				if (jj>=ss || TInt(iEntries[jj])<=si)
sl@0
   538
					break;
sl@0
   539
				iEntries[ii]=iEntries[jj];
sl@0
   540
				ii = jj;
sl@0
   541
				}
sl@0
   542
			iEntries[ii]=(TAny*)si;
sl@0
   543
			}
sl@0
   544
		}
sl@0
   545
	}
sl@0
   546
sl@0
   547
EXPORT_C void RPointerArrayBase::HeapSortUnsigned()
sl@0
   548
	{
sl@0
   549
	::HeapSortUnsigned((TUint*)iEntries,iCount);
sl@0
   550
	}
sl@0
   551
sl@0
   552
EXPORT_C void RPointerArrayBase::HeapSort(TGeneralLinearOrder anOrder)
sl@0
   553
	{
sl@0
   554
	TInt ss = iCount;
sl@0
   555
	if (ss>1)
sl@0
   556
		{
sl@0
   557
		TInt sh = ss>>1;
sl@0
   558
		FOREVER
sl@0
   559
			{
sl@0
   560
			TAny* si;
sl@0
   561
			if (sh!=0)
sl@0
   562
				{
sl@0
   563
				--sh;
sl@0
   564
				si = iEntries[sh];
sl@0
   565
				}
sl@0
   566
			else
sl@0
   567
				{
sl@0
   568
				--ss;
sl@0
   569
				si = iEntries[ss];
sl@0
   570
				iEntries[ss]=iEntries[0];
sl@0
   571
				if (ss==1)
sl@0
   572
					{
sl@0
   573
					iEntries[0]=si;
sl@0
   574
					break;
sl@0
   575
					}
sl@0
   576
				}
sl@0
   577
			TInt ii = sh;
sl@0
   578
			TInt jj = sh;
sl@0
   579
			FOREVER
sl@0
   580
				{
sl@0
   581
				jj = (jj+1)<<1;
sl@0
   582
				if (jj>=ss || (*anOrder)(iEntries[jj-1],iEntries[jj])>0 )
sl@0
   583
					--jj;
sl@0
   584
				if (jj>=ss || (*anOrder)(iEntries[jj],si)<=0 )
sl@0
   585
					break;
sl@0
   586
				iEntries[ii]=iEntries[jj];
sl@0
   587
				ii = jj;
sl@0
   588
				}
sl@0
   589
			iEntries[ii]=si;
sl@0
   590
			}
sl@0
   591
		}
sl@0
   592
	}
sl@0
   593
#endif
sl@0
   594
sl@0
   595
EXPORT_C TInt RPointerArrayBase::GetCount(const CBase* aPtr)
sl@0
   596
	{
sl@0
   597
	return ((RPointerArrayBase*)aPtr)->Count();
sl@0
   598
	}
sl@0
   599
sl@0
   600
EXPORT_C const TAny* RPointerArrayBase::GetElementPtr(const CBase* aPtr, TInt aIndex)
sl@0
   601
	{
sl@0
   602
	return &(((RPointerArrayBase*)aPtr)->At(aIndex));
sl@0
   603
	}
sl@0
   604
#endif	// __KERNEL_MODE__
sl@0
   605
sl@0
   606
EXPORT_C RArrayBase::RArrayBase(TInt anEntrySize)
sl@0
   607
	:	iCount(0), iEntries(NULL), iKeyOffset(0), iAllocated(0),
sl@0
   608
		iGranularity(KDefaultSimpleArrayGranularity), iSpare1(0), iSpare2(0)
sl@0
   609
	{
sl@0
   610
	__ASSERT_ALWAYS(anEntrySize>0 && anEntrySize<=KSimpleArrayMaxEntrySize,Panic(EBadArrayEntrySize));
sl@0
   611
	iEntrySize=(anEntrySize+(TInt)sizeof(TInt)-1)&~((TInt)sizeof(TInt)-1);
sl@0
   612
	}
sl@0
   613
sl@0
   614
EXPORT_C RArrayBase::RArrayBase(TInt anEntrySize, TInt aGranularity)
sl@0
   615
	:	iCount(0), iEntries(NULL), iKeyOffset(0), iAllocated(0),
sl@0
   616
		iGranularity(aGranularity), iSpare1(0), iSpare2(0)
sl@0
   617
	{
sl@0
   618
	__ASSERT_ALWAYS(anEntrySize>0 && anEntrySize<=KSimpleArrayMaxEntrySize,Panic(EBadArrayEntrySize));
sl@0
   619
	__ASSERT_ALWAYS(aGranularity>0 && (aGranularity*anEntrySize)<=KSimpleArrayMaxGranularity, Panic(EBadArrayGranularity));
sl@0
   620
	iEntrySize=(anEntrySize+(TInt)sizeof(TInt)-1)&~((TInt)sizeof(TInt)-1);
sl@0
   621
	}
sl@0
   622
sl@0
   623
EXPORT_C RArrayBase::RArrayBase(TInt aEntrySize,TAny* aEntries, TInt aCount)
sl@0
   624
	:	iCount(aCount), iEntries(aEntries), iKeyOffset(0), iAllocated(aCount),
sl@0
   625
		iGranularity(KDefaultSimpleArrayGranularity), iSpare1(0), iSpare2(0)
sl@0
   626
	{
sl@0
   627
	__ASSERT_ALWAYS(aEntrySize>0 && aEntrySize<=KSimpleArrayMaxEntrySize,Panic(EBadArrayEntrySize));
sl@0
   628
	__ASSERT_ALWAYS(aCount>0,Panic(EBadArrayCount));
sl@0
   629
	iEntrySize=(aEntrySize+(TInt)sizeof(TInt)-1)&~((TInt)sizeof(TInt)-1);
sl@0
   630
	}
sl@0
   631
sl@0
   632
EXPORT_C RArrayBase::RArrayBase(TInt anEntrySize, TInt aGranularity, TInt aKeyOffset)
sl@0
   633
	:	 iCount(0), iEntries(NULL), iKeyOffset(aKeyOffset), iAllocated(0),
sl@0
   634
		iGranularity(aGranularity), iSpare1(0), iSpare2(0)
sl@0
   635
	{
sl@0
   636
	__ASSERT_ALWAYS(anEntrySize>0 && anEntrySize<=KSimpleArrayMaxEntrySize,Panic(EBadArrayEntrySize));
sl@0
   637
	__ASSERT_ALWAYS(aGranularity>0 && (aGranularity*anEntrySize)<=KSimpleArrayMaxGranularity, Panic(EBadArrayGranularity));
sl@0
   638
	__ASSERT_ALWAYS(aKeyOffset>=0 && (aKeyOffset&3)==0 && aKeyOffset<anEntrySize, Panic(EBadArrayKeyOffset));
sl@0
   639
	iEntrySize=(anEntrySize+(TInt)sizeof(TInt)-1)&~((TInt)sizeof(TInt)-1);
sl@0
   640
	}
sl@0
   641
sl@0
   642
EXPORT_C RArrayBase::RArrayBase(TInt aEntrySize, TInt aMinGrowBy, TInt aKeyOffset, TInt aFactor)
sl@0
   643
	:	 iCount(0), iEntries(NULL), iKeyOffset(aKeyOffset), iAllocated(0), iSpare1(0), iSpare2(0)
sl@0
   644
	{
sl@0
   645
	__ASSERT_ALWAYS(aEntrySize>0 && aEntrySize<=KSimpleArrayMaxEntrySize, Panic(EBadArrayEntrySize));
sl@0
   646
	__ASSERT_ALWAYS(aKeyOffset>=0 && (aKeyOffset&3)==0 && aKeyOffset<aEntrySize, Panic(EBadArrayKeyOffset));
sl@0
   647
	__ASSERT_ALWAYS(aMinGrowBy>0 && aMinGrowBy<=KMaxArrayGrowBy, Panic(EBadArrayMinGrowBy));
sl@0
   648
	__ASSERT_ALWAYS(aFactor>=KMinArrayFactor && aFactor<=KMaxArrayFactor, Panic(EBadArrayFactor));
sl@0
   649
	iEntrySize=(aEntrySize+(TInt)sizeof(TInt)-1)&~((TInt)sizeof(TInt)-1);
sl@0
   650
	iGranularity = aMinGrowBy | (aFactor << 16) | 0x80000000;
sl@0
   651
	}
sl@0
   652
sl@0
   653
EXPORT_C void RArrayBase::Close()
sl@0
   654
	{
sl@0
   655
	iCount=0;
sl@0
   656
	STD_CLASS::Free(iEntries);
sl@0
   657
	iEntries=NULL;
sl@0
   658
	iAllocated=0;
sl@0
   659
	}
sl@0
   660
sl@0
   661
EXPORT_C TInt RArrayBase::Count() const
sl@0
   662
	{
sl@0
   663
	return iCount;
sl@0
   664
	}
sl@0
   665
sl@0
   666
#ifndef __ARRAY_MACHINE_CODED__
sl@0
   667
EXPORT_C TAny* RArrayBase::At(TInt anIndex) const
sl@0
   668
	{
sl@0
   669
	__ASSERT_ALWAYS((anIndex>=0 && anIndex<iCount),Panic(EBadArrayIndex));
sl@0
   670
	return (((TUint8*)iEntries)+anIndex*iEntrySize);
sl@0
   671
	}
sl@0
   672
#endif
sl@0
   673
sl@0
   674
TInt RArrayBase::Grow()
sl@0
   675
	{
sl@0
   676
	TInt newAlloc = CalculateArraySizeAfterGrow(iAllocated, iGranularity, KMaxTInt/iEntrySize);
sl@0
   677
	if (newAlloc < 0)
sl@0
   678
		return newAlloc;
sl@0
   679
	TAny** pA = (TAny**)STD_CLASS::ReAlloc(iEntries, newAlloc*iEntrySize);
sl@0
   680
	if (!pA)
sl@0
   681
		return KErrNoMemory;
sl@0
   682
	iEntries = pA;
sl@0
   683
	iAllocated = newAlloc;
sl@0
   684
	return KErrNone;
sl@0
   685
	}
sl@0
   686
sl@0
   687
#ifndef __ARRAY_MACHINE_CODED__
sl@0
   688
EXPORT_C TInt RArrayBase::Append(const TAny* anEntry)
sl@0
   689
	{
sl@0
   690
	if (iCount==iAllocated)
sl@0
   691
		{
sl@0
   692
		TInt r=Grow();
sl@0
   693
		if (r!=KErrNone)
sl@0
   694
			return r;
sl@0
   695
		}
sl@0
   696
	wordmove((TUint8*)iEntries+iCount*iEntrySize, anEntry, iEntrySize);
sl@0
   697
	iCount++;
sl@0
   698
	return KErrNone;
sl@0
   699
	}
sl@0
   700
#endif
sl@0
   701
sl@0
   702
EXPORT_C TInt RArrayBase::Insert(const TAny* anEntry, TInt aPos)
sl@0
   703
	{
sl@0
   704
	__ASSERT_ALWAYS((aPos>=0 && aPos<=iCount),Panic(EBadArrayPosition));
sl@0
   705
	if (iCount==iAllocated)
sl@0
   706
		{
sl@0
   707
		TInt r=Grow();
sl@0
   708
		if (r!=KErrNone)
sl@0
   709
			return r;
sl@0
   710
		}
sl@0
   711
	TUint8 *pS=(TUint8*)iEntries+aPos*iEntrySize;
sl@0
   712
	TUint8 *pD=pS+iEntrySize;
sl@0
   713
	TInt entries=iCount-aPos;
sl@0
   714
	if (entries!=0)
sl@0
   715
		wordmove(pD,pS,entries*iEntrySize);
sl@0
   716
	wordmove(pS,anEntry,iEntrySize);
sl@0
   717
	iCount++;
sl@0
   718
	return KErrNone;
sl@0
   719
	}
sl@0
   720
sl@0
   721
EXPORT_C void RArrayBase::Remove(TInt anIndex)
sl@0
   722
	{
sl@0
   723
	__ASSERT_ALWAYS((anIndex>=0 && anIndex<iCount),Panic(EBadArrayIndex));
sl@0
   724
	TUint8 *pD=(TUint8*)iEntries+anIndex*iEntrySize;
sl@0
   725
	TUint8 *pS=pD+iEntrySize;
sl@0
   726
	TInt entries=iCount-anIndex-1;
sl@0
   727
	if (entries!=0)
sl@0
   728
		wordmove(pD,pS,entries*iEntrySize);
sl@0
   729
	iCount--;
sl@0
   730
	}
sl@0
   731
sl@0
   732
EXPORT_C void RArrayBase::Compress()
sl@0
   733
	{
sl@0
   734
	if (iCount)
sl@0
   735
		iEntries=STD_CLASS::ReAlloc(iEntries,iCount*iEntrySize); // can't fail
sl@0
   736
	else
sl@0
   737
		{
sl@0
   738
		STD_CLASS::Free(iEntries);
sl@0
   739
		iEntries=NULL;
sl@0
   740
		}
sl@0
   741
	iAllocated=iCount;
sl@0
   742
	}
sl@0
   743
sl@0
   744
#ifndef __KERNEL_MODE__
sl@0
   745
EXPORT_C void RArrayBase::GranularCompress()
sl@0
   746
	{
sl@0
   747
	TInt newAlloc = CalculateArraySizeAfterShrink(iAllocated, iGranularity, iCount);
sl@0
   748
	if (newAlloc == iAllocated)
sl@0
   749
		return;
sl@0
   750
	if (newAlloc)
sl@0
   751
		iEntries=STD_CLASS::ReAlloc(iEntries,newAlloc*iEntrySize); // can't fail
sl@0
   752
	else
sl@0
   753
		{
sl@0
   754
		STD_CLASS::Free(iEntries);
sl@0
   755
		iEntries=NULL;
sl@0
   756
		}
sl@0
   757
	iAllocated=newAlloc;
sl@0
   758
	}
sl@0
   759
sl@0
   760
EXPORT_C TInt RArrayBase::DoReserve(TInt aCount)
sl@0
   761
	{
sl@0
   762
	__ASSERT_ALWAYS(aCount>=0, Panic(EArrayBadReserveCount));
sl@0
   763
	if (aCount <= iAllocated)
sl@0
   764
		return KErrNone;	// if allocated space is already sufficient, nothing to do
sl@0
   765
sl@0
   766
	Int64 size = Int64(aCount) * Int64(iEntrySize);
sl@0
   767
	if (size > Int64(KMaxTInt))
sl@0
   768
		return KErrNoMemory;
sl@0
   769
sl@0
   770
	TAny** pA = (TAny**)STD_CLASS::ReAlloc(iEntries, aCount*iEntrySize);
sl@0
   771
	if (!pA)
sl@0
   772
		return KErrNoMemory;
sl@0
   773
	iEntries = pA;
sl@0
   774
	iAllocated = aCount;
sl@0
   775
	return KErrNone;
sl@0
   776
	}
sl@0
   777
#endif
sl@0
   778
sl@0
   779
EXPORT_C void RArrayBase::Reset()
sl@0
   780
	{
sl@0
   781
	iCount=0;
sl@0
   782
	STD_CLASS::Free(iEntries);
sl@0
   783
	iEntries=NULL;
sl@0
   784
	iAllocated=0;
sl@0
   785
	}
sl@0
   786
sl@0
   787
EXPORT_C TInt RArrayBase::BinarySearch(const TAny* anEntry, TInt& anIndex, TGeneralLinearOrder anOrder) const
sl@0
   788
	{
sl@0
   789
	return BinarySearch(anEntry, anIndex, anOrder, EArrayFindMode_Any);
sl@0
   790
	}
sl@0
   791
sl@0
   792
#ifndef __ARRAY_MACHINE_CODED__
sl@0
   793
EXPORT_C TInt RArrayBase::Find(const TAny* anEntry) const
sl@0
   794
	{
sl@0
   795
	TUint8 *pS=(TUint8*)iEntries+iKeyOffset;
sl@0
   796
	TInt match=*(TInt*)((TUint8*)anEntry+iKeyOffset);
sl@0
   797
	TInt i;
sl@0
   798
	for (i=0; i<iCount; i++)
sl@0
   799
		{
sl@0
   800
		TInt key=*(TInt*)pS;
sl@0
   801
		if (key==match)
sl@0
   802
			return i;
sl@0
   803
		pS+=iEntrySize;
sl@0
   804
		}
sl@0
   805
	return KErrNotFound;
sl@0
   806
	}
sl@0
   807
sl@0
   808
EXPORT_C TInt RArrayBase::Find(const TAny* anEntry, TGeneralIdentityRelation anIdentity) const
sl@0
   809
	{
sl@0
   810
	TUint8 *pS=(TUint8*)iEntries;
sl@0
   811
	TInt i;
sl@0
   812
	for (i=0; i<iCount; i++)
sl@0
   813
		{
sl@0
   814
		if ((*anIdentity)(anEntry,pS))
sl@0
   815
			return i;
sl@0
   816
		pS+=iEntrySize;
sl@0
   817
		}
sl@0
   818
	return KErrNotFound;
sl@0
   819
	}
sl@0
   820
sl@0
   821
EXPORT_C TInt RArrayBase::BinarySearchSigned(const TAny* anEntry, TInt& anIndex) const
sl@0
   822
	{
sl@0
   823
	return BinarySearchSigned(anEntry, anIndex, EArrayFindMode_Any);
sl@0
   824
	}
sl@0
   825
sl@0
   826
EXPORT_C TInt RArrayBase::BinarySearchSigned(const TAny* anEntry, TInt& anIndex, TInt aMode) const
sl@0
   827
	{
sl@0
   828
	__ASSERT_DEBUG(TUint(aMode)<TUint(EArrayFindMode_Limit), Panic(EBadArrayFindMode));
sl@0
   829
	TInt match=*(TInt*)((TUint8*)anEntry+iKeyOffset);
sl@0
   830
	TUint8* pK=(TUint8*)iEntries+iKeyOffset;
sl@0
   831
	TInt l=0;
sl@0
   832
	TInt r=iCount;
sl@0
   833
	TInt ret = KErrNotFound;
sl@0
   834
	while(r>l)
sl@0
   835
		{
sl@0
   836
		TInt m=(l+r)>>1;
sl@0
   837
		TInt h=*(TInt*)(pK+m*iEntrySize);
sl@0
   838
		if (match==h)
sl@0
   839
			{
sl@0
   840
			if (aMode == EArrayFindMode_Any)
sl@0
   841
				{
sl@0
   842
				anIndex=m;
sl@0
   843
				return KErrNone;
sl@0
   844
				}
sl@0
   845
			ret = KErrNone;
sl@0
   846
			if (aMode == EArrayFindMode_First)
sl@0
   847
				r=m;
sl@0
   848
			else
sl@0
   849
				l=m+1;
sl@0
   850
			}
sl@0
   851
		else if (match>h)
sl@0
   852
			l=m+1;
sl@0
   853
		else
sl@0
   854
			r=m;
sl@0
   855
		}
sl@0
   856
	anIndex=r;
sl@0
   857
	return ret;
sl@0
   858
	}
sl@0
   859
sl@0
   860
EXPORT_C TInt RArrayBase::BinarySearchUnsigned(const TAny* anEntry, TInt& anIndex) const
sl@0
   861
	{
sl@0
   862
	return BinarySearchUnsigned(anEntry, anIndex, EArrayFindMode_Any);
sl@0
   863
	}
sl@0
   864
sl@0
   865
EXPORT_C TInt RArrayBase::BinarySearchUnsigned(const TAny* anEntry, TInt& anIndex, TInt aMode) const
sl@0
   866
	{
sl@0
   867
	__ASSERT_DEBUG(TUint(aMode)<TUint(EArrayFindMode_Limit), Panic(EBadArrayFindMode));
sl@0
   868
	TUint match=*(TUint*)((TUint8*)anEntry+iKeyOffset);
sl@0
   869
	TUint8* pK=(TUint8*)iEntries+iKeyOffset;
sl@0
   870
	TInt l=0;
sl@0
   871
	TInt r=iCount;
sl@0
   872
	TInt ret = KErrNotFound;
sl@0
   873
	while(r>l)
sl@0
   874
		{
sl@0
   875
		TInt m=(l+r)>>1;
sl@0
   876
		TUint h=*(TUint*)(pK+m*iEntrySize);
sl@0
   877
		if (match==h)
sl@0
   878
			{
sl@0
   879
			if (aMode == EArrayFindMode_Any)
sl@0
   880
				{
sl@0
   881
				anIndex=m;
sl@0
   882
				return KErrNone;
sl@0
   883
				}
sl@0
   884
			ret = KErrNone;
sl@0
   885
			if (aMode == EArrayFindMode_First)
sl@0
   886
				r=m;
sl@0
   887
			else
sl@0
   888
				l=m+1;
sl@0
   889
			}
sl@0
   890
		else if (match>h)
sl@0
   891
			l=m+1;
sl@0
   892
		else
sl@0
   893
			r=m;
sl@0
   894
		}
sl@0
   895
	anIndex=r;
sl@0
   896
	return ret;
sl@0
   897
	}
sl@0
   898
sl@0
   899
EXPORT_C TInt RArrayBase::BinarySearch(const TAny* anEntry, TInt& anIndex, TGeneralLinearOrder anOrder, TInt aMode) const
sl@0
   900
	{
sl@0
   901
	__ASSERT_DEBUG(TUint(aMode)<TUint(EArrayFindMode_Limit), Panic(EBadArrayFindMode));
sl@0
   902
	TInt l=0;
sl@0
   903
	TInt r=iCount;
sl@0
   904
	TInt ret = KErrNotFound;
sl@0
   905
	while(r>l)
sl@0
   906
		{
sl@0
   907
		TInt m=(l+r)>>1;
sl@0
   908
		TInt k=(*anOrder)(anEntry,(TUint8*)iEntries+m*iEntrySize);
sl@0
   909
		if (k==0)
sl@0
   910
			{
sl@0
   911
			if (aMode == EArrayFindMode_Any)
sl@0
   912
				{
sl@0
   913
				anIndex=m;
sl@0
   914
				return KErrNone;
sl@0
   915
				}
sl@0
   916
			ret = KErrNone;
sl@0
   917
			if (aMode == EArrayFindMode_First)
sl@0
   918
				r=m;
sl@0
   919
			else
sl@0
   920
				l=m+1;
sl@0
   921
			}
sl@0
   922
		else if (k>0)
sl@0
   923
			l=m+1;
sl@0
   924
		else
sl@0
   925
			r=m;
sl@0
   926
		}
sl@0
   927
	anIndex=r;
sl@0
   928
	return ret;
sl@0
   929
	}
sl@0
   930
sl@0
   931
EXPORT_C TInt RArrayBase::FindIsqSigned(const TAny* anEntry) const
sl@0
   932
	{
sl@0
   933
	return FindIsqSigned(anEntry, EArrayFindMode_Any);
sl@0
   934
	}
sl@0
   935
sl@0
   936
EXPORT_C TInt RArrayBase::FindIsqUnsigned(const TAny* anEntry) const
sl@0
   937
	{
sl@0
   938
	return FindIsqUnsigned(anEntry, EArrayFindMode_Any);
sl@0
   939
	}
sl@0
   940
sl@0
   941
EXPORT_C TInt RArrayBase::FindIsq(const TAny* anEntry, TGeneralLinearOrder anOrder) const
sl@0
   942
	{
sl@0
   943
	return FindIsq(anEntry, anOrder, EArrayFindMode_Any);
sl@0
   944
	}
sl@0
   945
sl@0
   946
EXPORT_C TInt RArrayBase::FindIsqSigned(const TAny* anEntry, TInt aMode) const
sl@0
   947
	{
sl@0
   948
	TInt i;
sl@0
   949
	TInt r=BinarySearchSigned(anEntry,i,aMode);
sl@0
   950
	return (r==KErrNone)?i:r;
sl@0
   951
	}
sl@0
   952
sl@0
   953
EXPORT_C TInt RArrayBase::FindIsqUnsigned(const TAny* anEntry, TInt aMode) const
sl@0
   954
	{
sl@0
   955
	TInt i;
sl@0
   956
	TInt r=BinarySearchUnsigned(anEntry,i,aMode);
sl@0
   957
	return (r==KErrNone)?i:r;
sl@0
   958
	}
sl@0
   959
sl@0
   960
EXPORT_C TInt RArrayBase::FindIsq(const TAny* anEntry, TGeneralLinearOrder anOrder, TInt aMode) const
sl@0
   961
	{
sl@0
   962
	TInt i;
sl@0
   963
	TInt r=BinarySearch(anEntry,i,anOrder,aMode);
sl@0
   964
	return (r==KErrNone)?i:r;
sl@0
   965
	}
sl@0
   966
#endif
sl@0
   967
sl@0
   968
EXPORT_C TInt RArrayBase::FindReverse(const TAny* anEntry) const
sl@0
   969
	{
sl@0
   970
	TUint8 *pS=(TUint8*)iEntries+(iCount-1)*iEntrySize+iKeyOffset;
sl@0
   971
	TInt match=*(TInt*)((TUint8*)anEntry+iKeyOffset);
sl@0
   972
	TInt i=iCount;
sl@0
   973
	while(i--)
sl@0
   974
		{
sl@0
   975
		TInt key=*(TInt*)pS;
sl@0
   976
		if (key==match)
sl@0
   977
			return i;
sl@0
   978
		pS-=iEntrySize;
sl@0
   979
		}
sl@0
   980
	return KErrNotFound;
sl@0
   981
	}
sl@0
   982
sl@0
   983
EXPORT_C TInt RArrayBase::FindReverse(const TAny* anEntry, TGeneralIdentityRelation anIdentity) const
sl@0
   984
	{
sl@0
   985
	TUint8 *pS=(TUint8*)iEntries+(iCount-1)*iEntrySize;
sl@0
   986
	TInt i=iCount;
sl@0
   987
	while (i--)
sl@0
   988
		{
sl@0
   989
		if ((*anIdentity)(anEntry,pS))
sl@0
   990
			return i;
sl@0
   991
		pS-=iEntrySize;
sl@0
   992
		}
sl@0
   993
	return KErrNotFound;
sl@0
   994
	}
sl@0
   995
sl@0
   996
EXPORT_C TInt RArrayBase::InsertIsqSigned(const TAny* anEntry, TBool aAllowRepeats)
sl@0
   997
	{
sl@0
   998
	TInt i;
sl@0
   999
	TInt mode = aAllowRepeats ? EArrayFindMode_Last : EArrayFindMode_Any;
sl@0
  1000
	TInt r=BinarySearchSigned(anEntry,i,mode);
sl@0
  1001
	if (r==KErrNotFound || aAllowRepeats)
sl@0
  1002
		return Insert((const TAny*)anEntry,i);
sl@0
  1003
	return KErrAlreadyExists;
sl@0
  1004
	}
sl@0
  1005
sl@0
  1006
EXPORT_C TInt RArrayBase::InsertIsqUnsigned(const TAny* anEntry, TBool aAllowRepeats)
sl@0
  1007
	{
sl@0
  1008
	TInt i;
sl@0
  1009
	TInt mode = aAllowRepeats ? EArrayFindMode_Last : EArrayFindMode_Any;
sl@0
  1010
	TInt r=BinarySearchUnsigned(anEntry,i,mode);
sl@0
  1011
	if (r==KErrNotFound || aAllowRepeats)
sl@0
  1012
		return Insert((const TAny*)anEntry,i);
sl@0
  1013
	return KErrAlreadyExists;
sl@0
  1014
	}
sl@0
  1015
sl@0
  1016
EXPORT_C TInt RArrayBase::InsertIsq(const TAny* anEntry, TGeneralLinearOrder anOrder, TBool aAllowRepeats)
sl@0
  1017
	{
sl@0
  1018
	TInt i;
sl@0
  1019
	TInt mode = aAllowRepeats ? EArrayFindMode_Last : EArrayFindMode_Any;
sl@0
  1020
	TInt r=BinarySearch(anEntry,i,anOrder,mode);
sl@0
  1021
	if (r==KErrNotFound || aAllowRepeats)
sl@0
  1022
		return Insert((const TAny*)anEntry,i);
sl@0
  1023
	return KErrAlreadyExists;
sl@0
  1024
	}
sl@0
  1025
sl@0
  1026
#ifndef __KERNEL_MODE__
sl@0
  1027
#ifndef __ARRAY_MACHINE_CODED__
sl@0
  1028
EXPORT_C void RArrayBase::HeapSortSigned()
sl@0
  1029
	{
sl@0
  1030
	TUint32 si[KSimpleArrayMaxEntrySize/4];
sl@0
  1031
	TInt ss = iCount;
sl@0
  1032
	if (ss>1)
sl@0
  1033
		{
sl@0
  1034
		TInt sh = ss>>1;
sl@0
  1035
		FOREVER
sl@0
  1036
			{
sl@0
  1037
			if (sh!=0)
sl@0
  1038
				{
sl@0
  1039
				--sh;
sl@0
  1040
				wordmove(si,(TUint8*)iEntries+sh*iEntrySize,iEntrySize);
sl@0
  1041
				}
sl@0
  1042
			else
sl@0
  1043
				{
sl@0
  1044
				--ss;
sl@0
  1045
				wordmove(si,(TUint8*)iEntries+ss*iEntrySize,iEntrySize);
sl@0
  1046
				wordmove((TUint8*)iEntries+ss*iEntrySize,iEntries,iEntrySize);
sl@0
  1047
				if (ss==1)
sl@0
  1048
					{
sl@0
  1049
					wordmove(iEntries,si,iEntrySize);
sl@0
  1050
					break;
sl@0
  1051
					}
sl@0
  1052
				}
sl@0
  1053
			TInt ii = sh;
sl@0
  1054
			TInt jj = sh;
sl@0
  1055
			TInt sikey=*(TInt*)((TUint8*)si+iKeyOffset);
sl@0
  1056
			FOREVER
sl@0
  1057
				{
sl@0
  1058
				jj = (jj+1)<<1;
sl@0
  1059
				TUint8* pKey=((TUint8*)iEntries+jj*iEntrySize+iKeyOffset);
sl@0
  1060
				if (jj>=ss || (*(TInt*)(pKey-iEntrySize))>*(TInt*)pKey )
sl@0
  1061
					{
sl@0
  1062
					--jj;
sl@0
  1063
					pKey-=iEntrySize;
sl@0
  1064
					}
sl@0
  1065
				if (jj>=ss || *(TInt*)pKey<=sikey)
sl@0
  1066
					break;
sl@0
  1067
				wordmove((TUint8*)iEntries+ii*iEntrySize,(TUint8*)iEntries+jj*iEntrySize,iEntrySize);
sl@0
  1068
				ii = jj;
sl@0
  1069
				}
sl@0
  1070
			wordmove((TUint8*)iEntries+ii*iEntrySize,si,iEntrySize);
sl@0
  1071
			}
sl@0
  1072
		}
sl@0
  1073
	}
sl@0
  1074
sl@0
  1075
EXPORT_C void RArrayBase::HeapSortUnsigned()
sl@0
  1076
	{
sl@0
  1077
	TUint32 si[KSimpleArrayMaxEntrySize/4];
sl@0
  1078
	TInt ss = iCount;
sl@0
  1079
	if (ss>1)
sl@0
  1080
		{
sl@0
  1081
		TInt sh = ss>>1;
sl@0
  1082
		FOREVER
sl@0
  1083
			{
sl@0
  1084
			if (sh!=0)
sl@0
  1085
				{
sl@0
  1086
				--sh;
sl@0
  1087
				wordmove(si,(TUint8*)iEntries+sh*iEntrySize,iEntrySize);
sl@0
  1088
				}
sl@0
  1089
			else
sl@0
  1090
				{
sl@0
  1091
				--ss;
sl@0
  1092
				wordmove(si,(TUint8*)iEntries+ss*iEntrySize,iEntrySize);
sl@0
  1093
				wordmove((TUint8*)iEntries+ss*iEntrySize,iEntries,iEntrySize);
sl@0
  1094
				if (ss==1)
sl@0
  1095
					{
sl@0
  1096
					wordmove(iEntries,si,iEntrySize);
sl@0
  1097
					break;
sl@0
  1098
					}
sl@0
  1099
				}
sl@0
  1100
			TInt ii = sh;
sl@0
  1101
			TInt jj = sh;
sl@0
  1102
			TUint sikey=*(TUint*)((TUint8*)si+iKeyOffset);
sl@0
  1103
			FOREVER
sl@0
  1104
				{
sl@0
  1105
				jj = (jj+1)<<1;
sl@0
  1106
				TUint8* pKey=((TUint8*)iEntries+jj*iEntrySize+iKeyOffset);
sl@0
  1107
				if (jj>=ss || (*(TUint*)(pKey-iEntrySize))>*(TUint*)pKey )
sl@0
  1108
					{
sl@0
  1109
					--jj;
sl@0
  1110
					pKey-=iEntrySize;
sl@0
  1111
					}
sl@0
  1112
				if (jj>=ss || *(TUint*)pKey<=sikey)
sl@0
  1113
					break;
sl@0
  1114
				wordmove((TUint8*)iEntries+ii*iEntrySize,(TUint8*)iEntries+jj*iEntrySize,iEntrySize);
sl@0
  1115
				ii = jj;
sl@0
  1116
				}
sl@0
  1117
			wordmove((TUint8*)iEntries+ii*iEntrySize,si,iEntrySize);
sl@0
  1118
			}
sl@0
  1119
		}
sl@0
  1120
	}
sl@0
  1121
sl@0
  1122
EXPORT_C void RArrayBase::HeapSort(TGeneralLinearOrder anOrder)
sl@0
  1123
	{
sl@0
  1124
	TUint32 si[KSimpleArrayMaxEntrySize/4];
sl@0
  1125
	TInt ss = iCount;
sl@0
  1126
	if (ss>1)
sl@0
  1127
		{
sl@0
  1128
		TInt sh = ss>>1;
sl@0
  1129
		FOREVER
sl@0
  1130
			{
sl@0
  1131
			if (sh!=0)
sl@0
  1132
				{
sl@0
  1133
				--sh;
sl@0
  1134
				wordmove(si,(TUint8*)iEntries+sh*iEntrySize,iEntrySize);
sl@0
  1135
				}
sl@0
  1136
			else
sl@0
  1137
				{
sl@0
  1138
				--ss;
sl@0
  1139
				wordmove(si,(TUint8*)iEntries+ss*iEntrySize,iEntrySize);
sl@0
  1140
				wordmove((TUint8*)iEntries+ss*iEntrySize,iEntries,iEntrySize);
sl@0
  1141
				if (ss==1)
sl@0
  1142
					{
sl@0
  1143
					wordmove(iEntries,si,iEntrySize);
sl@0
  1144
					break;
sl@0
  1145
					}
sl@0
  1146
				}
sl@0
  1147
			TInt ii = sh;
sl@0
  1148
			TInt jj = sh;
sl@0
  1149
			FOREVER
sl@0
  1150
				{
sl@0
  1151
				jj = (jj+1)<<1;
sl@0
  1152
				TUint8* pJJ=((TUint8*)iEntries+jj*iEntrySize);
sl@0
  1153
				if (jj>=ss || (*anOrder)(pJJ-iEntrySize,pJJ)>0)
sl@0
  1154
					{
sl@0
  1155
					--jj;
sl@0
  1156
					pJJ-=iEntrySize;
sl@0
  1157
					}
sl@0
  1158
				if (jj>=ss || (*anOrder)(pJJ,si)<=0)
sl@0
  1159
					break;
sl@0
  1160
				wordmove((TUint8*)iEntries+ii*iEntrySize,(TUint8*)iEntries+jj*iEntrySize,iEntrySize);
sl@0
  1161
				ii = jj;
sl@0
  1162
				}
sl@0
  1163
			wordmove((TUint8*)iEntries+ii*iEntrySize,si,iEntrySize);
sl@0
  1164
			}
sl@0
  1165
		}
sl@0
  1166
	}
sl@0
  1167
#endif
sl@0
  1168
sl@0
  1169
EXPORT_C TInt RArrayBase::GetCount(const CBase* aPtr)
sl@0
  1170
	{
sl@0
  1171
	return ((RArrayBase*)aPtr)->Count();
sl@0
  1172
	}
sl@0
  1173
sl@0
  1174
EXPORT_C const TAny* RArrayBase::GetElementPtr(const CBase* aPtr, TInt aIndex)
sl@0
  1175
	{
sl@0
  1176
	return ((RArrayBase*)aPtr)->At(aIndex);
sl@0
  1177
	}
sl@0
  1178
#endif	// __KERNEL_MODE__
sl@0
  1179