Fix for bug 2283 (RVCT 4.0 support is missing from PDK 3.0.h)
Have multiple extension sections in the bld.inf, one for each version
of the compiler. The RVCT version building the tools will build the
runtime libraries for its version, but make sure we extract all the other
versions from zip archives. Also add the archive for RVCT4.
// Copyright (c) 1996-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
//
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//!!
//!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
//!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#include "sl_std.h"
//-----------------------------------------------------------------------------
/**
Removes trailing dots from aName.
@return new string descriptor that may have its length adjusted
*/
TPtrC RemoveTrailingDots(const TDesC& aName)
{
TInt len = aName.Length();
while(len > 0)
{
if(aName[len-1] == '.')
len--;
else
break;
}
TPtrC ptrNoDots(aName.Ptr(), len);
return ptrNoDots;
}
TUint32 Log2(TUint32 aVal)
{
__ASSERT_COMPILE(sizeof(TUint32) == 4);
ASSERT(aVal);
TUint32 bitPos=31;
if(!(aVal >> 16)) {bitPos-=16; aVal<<=16;}
if(!(aVal >> 24)) {bitPos-=8; aVal<<=8 ;}
if(!(aVal >> 28)) {bitPos-=4; aVal<<=4 ;}
if(!(aVal >> 30)) {bitPos-=2; aVal<<=2 ;}
if(!(aVal >> 31)) {bitPos-=1;}
return bitPos;
}
TTime DosTimeToTTime(TInt aDosTime,TInt aDosDate)
//
// Deciphers the dos time/date entry information and converts to TTime
//
{
TInt secMask=0x1F;
TInt minMask=0x07E0;
TInt hrMask=0xF800;
TInt dayMask=0x1F;
TInt monthMask=0x01E0;
TInt yearMask=0xFE00;
TInt secs=(aDosTime&secMask)*2;
TInt mins=(aDosTime&minMask)>>5;
TInt hrs=(aDosTime&hrMask)>>11;
TInt days=(aDosDate&dayMask)-1;
TMonth months=(TMonth)(((aDosDate&monthMask)>>5)-1);
TInt years=((aDosDate&yearMask)>>9)+1980;
TDateTime datetime;
TInt ret=datetime.Set(years,months,days,hrs,mins,secs,0);
if (ret==KErrNone)
return(TTime(datetime));
return(TTime(0));
}
TInt DosTimeFromTTime(const TTime& aTime)
//
// Converts a TTime to a dos time
//
{
TDateTime dateTime=aTime.DateTime();
TInt dosSecs=dateTime.Second()/2;
TInt dosMins=dateTime.Minute()<<5;
TInt dosHrs=dateTime.Hour()<<11;
return dosSecs|dosMins|dosHrs;
}
TInt DosDateFromTTime(const TTime& aTime)
//
// Converts a TTime to a dos date
//
{
TDateTime dateTime=aTime.DateTime();
TInt dosDays=dateTime.Day()+1;
TInt dosMonths=(dateTime.Month()+1)<<5;
TInt dosYears=(dateTime.Year()-1980)<<9;
return dosDays|dosMonths|dosYears;
}
TBuf8<12> DosNameToStdFormat(const TDesC8& aDosName)
//
// Converts xxx.yyy to standard format aaaaaaaayyy
//
{
__ASSERT_DEBUG(aDosName.Length()>=0 && aDosName.Length()<=12,Fault(EFatBadDosFormatName));
TBuf8<12> result;
Mem::Fill((TUint8*)result.Ptr(),result.MaxSize(),' ');
TInt dotPos=aDosName.Locate('.');
if (dotPos==KErrNotFound)
{
result=aDosName;
result.SetLength(11);
return result;
}
result=aDosName.Left(dotPos);
result.SetLength(11);
TPtr8 ext(&result[8],3);
ext=aDosName.Right(aDosName.Length()-dotPos-1);
return result;
}
TBuf8<12> DosNameFromStdFormat(const TDesC8& aStdFormatName)
//
// Converts aaaaaaaayyy to dos name format xxx.yyy
//
{
__ASSERT_DEBUG(aStdFormatName.Length()==11,Fault(EFatBadStdFormatName));
TBuf8<12> result;
TInt nameLen=aStdFormatName.Locate(' ');
if (nameLen>8 || nameLen==KErrNotFound)
nameLen=8;
result=aStdFormatName.Left(nameLen);
TPtrC8 ext(&aStdFormatName[8],3);
TInt extLen=ext.Locate(' ');
if (extLen)
result.Append(TChar('.'));
if (extLen==KErrNotFound)
extLen=3;
result.Append(ext.Left(extLen));
if(result.Length() && result[0]==0x05 )
{
result[0]=0xE5;
}
return result;
}
TInt NumberOfVFatEntries(TInt aNameLength)
//
// Return the number of VFat entries required to describe a filename of length aNameLength
//
{
TInt numberOfEntries=0;
if (aNameLength%KMaxVFatEntryName)
aNameLength++; // Include a zero terminator
// If aNameLength is a exact multiple of KMaxVFatEntryName, don't bother
// with a zero terminator - it just adds an unnecessary directory entry
numberOfEntries=(1+(aNameLength/KMaxVFatEntryName));
if (aNameLength%KMaxVFatEntryName)
numberOfEntries++;
return(numberOfEntries);
}
//-----------------------------------------------------------------------------
/**
Calculate DOS short name checksum
@param aShortName short name descriptor (must be at least 11 bytes long)
@return checksum
*/
TUint8 CalculateShortNameCheckSum(const TDesC8& aShortName)
{
ASSERT(aShortName.Length() >= KFatDirNameSize);
const TUint8* pName = aShortName.Ptr();
const TUint32 w0 = ((const TUint32*)pName)[0];
const TUint32 w1 = ((const TUint32*)pName)[1];
TUint32 chkSum = w0 & 0xFF;
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + ((w0 << 16) >> 24));
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + ((w0 << 8) >> 24));
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + ( w0 >> 24));
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + (w1) & 0xFF);
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + ((w1 << 16) >> 24));
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + ((w1 << 8) >> 24));
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + ( w1 >> 24));
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + pName[8]);
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + pName[9]);
chkSum = (TUint8)(((chkSum<<7) | (chkSum>>1)) + pName[10]);
return (TUint8)chkSum;
}
//-----------------------------------------------------------------------------
const TUint32 K_FFFF = 0xFFFFFFFF; //-- all one bits, beware rigth shifts of signed integers!
RBitVector::RBitVector()
:iNumBits(0), ipData(NULL), iNumWords(0)
{
}
RBitVector::~RBitVector()
{
Close();
}
/**
Panics.
@param aPanicCode a panic code
*/
void RBitVector::Panic(TPanicCode aPanicCode) const
{
_LIT(KPanicCat,"RBitVector");
User::Panic(KPanicCat, aPanicCode);
}
/** explicitly closes the object and deallocates memory */
void RBitVector::Close()
{
iNumBits = 0;
iNumWords =0;
User::Free(ipData);
ipData = NULL;
}
//-----------------------------------------------------------------------------
/**
Comparison perator.
@param aRhs a vector to compate with.
@panic ESizeMismatch in the case of different vector sizes
*/
TBool RBitVector::operator==(const RBitVector& aRhs) const
{
__ASSERT_ALWAYS(ipData, Panic(ENotInitialised));
__ASSERT_ALWAYS(iNumBits == aRhs.iNumBits, Panic(ESizeMismatch));
if(!iNumBits)
return ETrue; //-- comparing 0-lenght arrays
if(this == &aRhs)
return ETrue; //-- comparing with itself
if(iNumWords >= 1)
{
const TUint32 cntBytes = (iNumBits >> 5) << 2; //-- bytes to compare
if(memcompare((const TUint8*)ipData, cntBytes, (const TUint8*)aRhs.ipData, cntBytes))
return EFalse;
}
const TUint32 bitsRest = iNumBits & 0x1F;
if(bitsRest)
{
const TUint32 mask = K_FFFF >> (32-bitsRest);
return ( (ipData[iNumWords-1] & mask) == (aRhs.ipData[iNumWords-1] & mask) );
}
return ETrue;
}
TBool RBitVector::operator!=(const RBitVector& aRhs) const
{
return ! ((*this) == aRhs);
}
//-----------------------------------------------------------------------------
/** The same as Create(), but leaves on error */
void RBitVector::CreateL(TUint32 aNumBits)
{
User::LeaveIfError(Create(aNumBits));
}
/**
Create the vector with the size of aNumBits bits.
@return system-wide error codes:
KErrNoMemory unable to allocate sufficient amount of memory for the array
KErrInUse an attempt to call Create() for non-empty vector. Close it first.
KErrArgument invalid aNumBits value == 0
*/
TInt RBitVector::Create(TUint32 aNumBits)
{
if(ipData)
return KErrInUse; //-- array is already in use. Close it first.
if(!aNumBits)
return KErrArgument;
//-- memory is allocated by word (32 bit) quiantities
const TUint32 numWords = (aNumBits >> 5) + ((aNumBits & 0x1F) > 0 ? 1:0);
ipData = (TUint32*)User::AllocZ(numWords << 2);
if(!ipData)
return KErrNoMemory;
iNumBits = aNumBits;
iNumWords = numWords;
return KErrNone;
}
/**
Fill a bit vector with a given bit value
@param aVal a bit value
*/
void RBitVector::Fill(TBool aVal)
{
__ASSERT_ALWAYS(ipData, Panic(ENotInitialised));
memset(ipData, (aVal ? 0xFF : 0x00), iNumWords << 2);
}
/** Invert all bits in a bit vector */
void RBitVector::Invert()
{
__ASSERT_ALWAYS(ipData, Panic(ENotInitialised));
for(TUint32 i=0; i<iNumWords; ++i)
ipData[i] ^= K_FFFF;
}
/**
Perform "And" operation between 2 vectors. They shall be the same size.
@param aRhs a vector from the right hand side
@panic ESizeMismatch in the case of different vector sizes
*/
void RBitVector::And(const RBitVector& aRhs)
{
__ASSERT_ALWAYS(ipData, Panic(ENotInitialised));
__ASSERT_ALWAYS(iNumBits == aRhs.iNumBits, Panic(ESizeMismatch));
for(TUint32 i=0; i<iNumWords; ++i)
{
ipData[i] &= aRhs.ipData[i];
}
}
/**
Perform "Or" operation between 2 vectors. They shall be the same size.
@param aRhs a vector from the right hand side
@panic ESizeMismatch in the case of different vector sizes
*/
void RBitVector::Or(const RBitVector& aRhs)
{
__ASSERT_ALWAYS(ipData, Panic(ENotInitialised));
__ASSERT_ALWAYS(iNumBits == aRhs.iNumBits, Panic(ESizeMismatch));
for(TUint32 i=0; i<iNumWords; ++i)
{
ipData[i] |= aRhs.ipData[i];
}
}
/**
Perform "Xor" operation between 2 vectors. They shall be the same size.
@param aRhs a vector from the right hand side
@panic ESizeMismatch in the case of different vector sizes
*/
void RBitVector::Xor(const RBitVector& aRhs)
{
__ASSERT_ALWAYS(ipData, Panic(ENotInitialised));
__ASSERT_ALWAYS(iNumBits == aRhs.iNumBits, Panic(ESizeMismatch));
for(TUint32 i=0; i<iNumWords; ++i)
{
ipData[i] ^= aRhs.ipData[i];
}
}
//-----------------------------------------------------------------------------
/**
Fill a range from bit number "aIndexFrom" to "aIndexTo" inclusively with the value of aVal
@param aIndexFrom start bit number (inclusive)
@param aIndexTo end bit number (inclusive)
@param aVal the value to be used to fill the range (0s or 1s)
*/
void RBitVector::Fill(TUint32 aIndexFrom, TUint32 aIndexTo, TBool aVal)
{
__ASSERT_ALWAYS(ipData, Panic(ENotInitialised));
//-- swap indexes if they are not in order
if(aIndexFrom > aIndexTo)
{
const TUint32 tmp = aIndexFrom;
aIndexFrom = aIndexTo;
aIndexTo = tmp;
}
__ASSERT_ALWAYS((aIndexFrom < iNumBits) && (aIndexTo < iNumBits), Panic(EIndexOutOfRange));
const TUint32 wordStart = WordNum(aIndexFrom);
const TUint32 wordTo = WordNum(aIndexTo);
if(aVal)
{//-- filling a range with '1'
TUint32 shift = BitInWord(aIndexFrom);
const TUint32 mask1 = (K_FFFF >> shift) << shift;
TUint32 mask2 = K_FFFF;
shift = 1+BitInWord(aIndexTo);
if(shift < 32)
{
mask2 = ~((mask2 >> shift) << shift);
}
if(wordTo == wordStart)
{//-- a special case, filling is in the same word
ipData[wordStart] |= (mask1 & mask2);
}
else
{
ipData[wordStart] |= mask1;
ipData[wordTo] |= mask2;
const TUint32 wholeWordsBetween = wordTo - wordStart - 1; //-- whole words that can be bulk filled
if(wholeWordsBetween)
memset(ipData+wordStart+1, 0xFF, wholeWordsBetween << 2);
}
}
else
{//-- filling a range with '0'
//-- if you need this functionality, remove the panic and uncomment the code below.
Panic(ENotImplemented);
/*
TUint32 shift = BitInWord(aIndexFrom);
const TUint32 mask1 = ~((K_FFFF >> shift) << shift);
TUint32 mask2 = 0;
shift = 1+BitInWord(aIndexTo);
if(shift < 32)
{
mask2 = ((K_FFFF >> shift) << shift);
}
if(wordTo == wordStart)
{//-- a special case, filling is in the same word
ipData[wordStart] &= (mask1 | mask2);
}
else
{
ipData[wordStart] &= mask1;
ipData[wordTo] &= mask2;
const TUint32 wholeWordsBetween = wordTo - wordStart - 1; //-- whole words that can be bulk filled
if(wholeWordsBetween)
memset(ipData+wordStart+1, 0x00, wholeWordsBetween << 2);
}
*/
}
}
//-----------------------------------------------------------------------------
/**
Search for a specified bit value ('0' or '1') in the vector from the given position.
@param aStartPos zero-based index; from this position the search will start. This position isn't included to the search.
On return may contain a new position if the specified bit is found in specified direction.
@param aBitVal zero or non-zero bit to search.
@param aDir Specifies the search direction
@return ETrue if the specified bit value is found; aStartPos gets updated.
EFalse otherwise.
*/
TBool RBitVector::Find(TUint32& aStartPos, TBool aBitVal, TFindDirection aDir) const
{
__ASSERT_ALWAYS(aStartPos < iNumBits, Panic(EIndexOutOfRange));
ASSERT(iNumWords && ipData);
switch(aDir)
{
case ERight: //-- Search from the given position to the right
return FindToRight(aStartPos, aBitVal);
case ELeft: //-- Search from the given position to the left (towards lower index)
return FindToLeft(aStartPos, aBitVal);
case ENearestL: //-- Search for the nearest value in both directions starting from left
return FindNearest(aStartPos, aBitVal, ETrue);
case ENearestR: //-- Search for the nearest value in both directions starting from right
return FindNearest(aStartPos, aBitVal, EFalse);
default:
Panic(EWrondFindDirection);
return EFalse;
};
}
//-----------------------------------------------------------------------------
/**
Internal method to look for a given bit value in the right direction.
see TBool RBitVector::Find(...)
*/
TBool RBitVector::FindToRight(TUint32& aStartPos, TBool aBitVal) const
{
if(aStartPos >= iNumBits-1)
return EFalse; //-- no way to the right
const TUint32 startPos = aStartPos+1;
const TUint32 fInvert = aBitVal ? 0 : K_FFFF; //-- invert everything if we are looking for '0' bit
TUint32 wordNum = WordNum(startPos);
TUint32 val = ipData[wordNum] ^ fInvert;
if(wordNum == iNumWords-1)
{//-- process the last word in the array, some higher bits might not belong to the bit vector
val = MaskLastWord(val);
}
const TUint32 shift = BitInWord(startPos);
val = (val >> shift) << shift; //-- mask unused low bits
if(val)
{//-- there are '1' bits in the current word
goto found;
}
else
{//-- search in higher words
wordNum++;
while(iNumWords-wordNum > 1)
{
val = ipData[wordNum] ^ fInvert;
if(val)
goto found;
wordNum++;
}
if(wordNum == iNumWords-1)
{//-- process the last word in the array, some higher bith might not belong to the bit vector
val = ipData[wordNum] ^ fInvert;
val = MaskLastWord(val);
if(val)
goto found;
}
}
return EFalse; //-- haven't found anything
found:
val &= (~val+1); //-- select rightmost bit
aStartPos = (wordNum << 5)+Log2(val);
return ETrue;
}
//-----------------------------------------------------------------------------
/**
Internal method to look for a given bit value in the left direction.
see TBool RBitVector::Find(...)
*/
TBool RBitVector::FindToLeft(TUint32& aStartPos, TBool aBitVal) const
{
if(!aStartPos)
return EFalse; //-- no way to the left
const TUint32 startPos=aStartPos-1;
const TUint32 fInvert = aBitVal ? 0 : K_FFFF; //-- invert everything if we are looking for '0' bit
TUint32 wordNum = WordNum(startPos);
TUint32 val = ipData[wordNum] ^ fInvert;
const TUint32 shift = 31-(BitInWord(startPos));
val = (val << shift) >> shift; //-- mask unused high bits
if(val)
{//-- there are '1' bits in the current word
goto found;
}
else
{//-- search in the lower words
while(wordNum)
{
wordNum--;
val=ipData[wordNum] ^ fInvert;
if(val)
goto found;
}
}
return EFalse; //-- nothing found
found:
aStartPos = (wordNum << 5)+Log2(val);
return ETrue;
}
//-----------------------------------------------------------------------------
/**
Internal method to look for a given bit value in the both directions.
see TBool RBitVector::Find(...)
*/
TBool RBitVector::FindNearest(TUint32& aStartPos, TBool aBitVal, TBool aToLeft) const
{
if(iNumBits < 2)
return EFalse;
if(aStartPos == 0)
return FindToRight(aStartPos, aBitVal);
if(aStartPos == iNumBits-1)
return FindToLeft(aStartPos, aBitVal);
const TUint32 fInvert = aBitVal ? 0 : K_FFFF; //-- invert everything if we are looking for '0' bit
TUint32 wordNum = WordNum(aStartPos);
TUint32 l_Idx; //-- index of the word to the left
TUint32 r_Idx; //-- index of the word to the right
l_Idx = r_Idx = wordNum;
TBool noWayLeft = (wordNum == 0); //-- if we are in the first word
TBool noWayRight = (wordNum == iNumWords-1); //-- if we are in the last word
//-- look in the current word first
TUint32 val = ipData[wordNum] ^ fInvert;
if(noWayRight)
{ //-- this is the last word in the array, mask unused high bits in the last word
val = MaskLastWord(val);
}
const TUint32 bitPos = aStartPos & 0x1F;
val &= ~(1<<bitPos); //-- mask the bit at current position
if(val == 0)
{//-- no '1' bits in the current word
noWayLeft = ItrLeft(l_Idx);
noWayRight = ItrRight(r_Idx);
}
else if(bitPos == 0)
{
noWayLeft = ItrLeft(l_Idx); //-- move to the previous word
}
else if(bitPos == 31)
{
noWayRight = ItrRight(r_Idx); //-- move to the next word
}
else
{//-- look in the current word, in both halves to the left and right from the start position
const TUint32 shift1 = 32-bitPos;
const TUint32 partLo = (val << shift1) >> shift1; //-- towards lower bits
const TUint32 shift2 = bitPos+1;
const TUint32 partHi = (val >> shift2) << shift2; //-- towards higher bits
if(partLo && !partHi) //-- only lower part has '1' bits
{
aStartPos = (wordNum << 5)+Log2(partLo);
return ETrue;
}
else if(!partLo && partHi) //-- only higher part has '1' bits
{
aStartPos = (wordNum << 5)+Log2( (partHi & (~partHi+1)) );
return ETrue;
}
else if(partLo && partHi) //-- both parts contain '1' bits, select the nearest one
{
const TUint32 posL = (wordNum << 5)+Log2(partLo);
const TUint32 posR = (wordNum << 5)+Log2( (partHi & (~partHi+1)) );
ASSERT(aStartPos > posL);
ASSERT(posR > aStartPos);
const TUint32 distL = aStartPos-posL;
const TUint32 distR = posR-aStartPos;
if(distL < distR)
{
aStartPos = posL;
return ETrue;
}
else if(distL > distR)
{
aStartPos = posR;
return ETrue;
}
else
{//-- distL == distR, take into account search priority
aStartPos = aToLeft ? posL : posR;
return ETrue;
}
}
else //-- (!partLo && !partHi), nothing in the current word
{
ASSERT(0);
}
}// if(bitPos > 0 && bitPos < 31)
//-- now we are processing separate words from both sides of the search position
for(;;)
{
TUint32 wL = ipData[l_Idx] ^ fInvert;
TUint32 wR = ipData[r_Idx] ^ fInvert;
if(r_Idx == iNumWords-1)
{ //-- this is the last word in the array, mask unused high bits in the last word
wR = MaskLastWord(wR);
}
if(wL && !wR)
{
aStartPos = (l_Idx << 5)+Log2(wL);
return ETrue;
}
else if(!wL && wR)
{
aStartPos = (r_Idx << 5)+Log2( (wR & (~wR+1)) );
return ETrue;
}
else if(wL && wR)
{
const TUint32 posL = (l_Idx << 5)+Log2(wL);
const TUint32 posR = (r_Idx << 5)+Log2( (wR & (~wR+1)) );
ASSERT(aStartPos > posL);
ASSERT(posR > aStartPos);
const TUint32 distL = aStartPos-posL;
const TUint32 distR = posR-aStartPos;
if(distL < distR)
{
aStartPos = posL;
return ETrue;
}
else if(distL > distR)
{
aStartPos = posR;
return ETrue;
}
else
{//-- distL == distR, take into account search priority
aStartPos = aToLeft ? posL : posR;
return ETrue;
}
}//else if(wL && wR)
if(noWayLeft)
{
aStartPos = r_Idx << 5;
return FindToRight(aStartPos, aBitVal);
}
else
{
noWayLeft = ItrLeft(l_Idx);
}
if(noWayRight)
{
aStartPos = l_Idx << 5;
return FindToLeft(aStartPos, aBitVal);
}
else
{
noWayRight = ItrRight(r_Idx);
}
}//for(;;)
//return EFalse;
}
//-----------------------------------------------------------------------------
/**
Find out if two vectors are different.
@param aRhs vector to compare with
@param aDiffIndex if there is a differene, here will be the number of the first different bit
@return ETrue if vectors differ, EFalse, if they are identical.
*/
TBool RBitVector::Diff(const RBitVector& aRhs, TUint32& aDiffIndex) const
{
__ASSERT_ALWAYS(ipData, Panic(ENotInitialised));
__ASSERT_ALWAYS(iNumBits == aRhs.iNumBits, Panic(ESizeMismatch));
ASSERT(iNumWords > 0);
TUint32 diffWord=0;
TUint32 wordNum=0;
//-- compare all but the last word in the array
for(wordNum=0; wordNum < iNumWords-1; ++wordNum)
{
diffWord = ipData[wordNum] ^ aRhs.ipData[wordNum];
if(diffWord)
break; //-- found difference
}
//-- process the last word in the array
if(!diffWord)
{
diffWord = MaskLastWord(ipData[wordNum]) ^ MaskLastWord(aRhs.ipData[wordNum]);
}
if(!diffWord)
return EFalse; //-- vectors are the same
//-- calculate the position of the bit that different.
diffWord &= (~diffWord+1); //-- select rightmost bit
aDiffIndex = (wordNum << 5)+Log2(diffWord);
return ETrue;
}
//-----------------------------------------------------------------------------
/**
Iterate to the left (towards lower index) in the array of words ipData
@param aIdx index within ipData array to be decremented; if it's possible to move left, it will be decreased
@return ETrue if there is no way left i.e. aIdx is 0. EFalse otherwise and aIdx decreased.
*/
TBool RBitVector::ItrLeft(TUint32& aIdx) const
{
if(aIdx == 0)
return ETrue;
else
{
aIdx--;
return EFalse;
}
}
/**
Iterate to the right (towards higher index) in the array of words ipData
@param aIdx index within ipData array to be incremented; if it's possible to move right, it will be increased
@return ETrue if there is no way right i.e. aIdx corresponds to the last word. EFalse otherwise and aIdx increased.
*/
TBool RBitVector::ItrRight(TUint32& aIdx) const
{
if(aIdx < iNumWords-1)
{
aIdx++;
return EFalse;
}
else
return ETrue;
}