sl@0: /* sl@0: * Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * sl@0: */ sl@0: sl@0: sl@0: #ifndef REMOVE_CAF1 sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: using namespace ContentAccess; sl@0: sl@0: EXPORT_C CBitset* CBitset::NewLC(TInt aMaxBits) sl@0: { sl@0: CBitset* self = new(ELeave) CBitset(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aMaxBits); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CBitset* CBitset::NewL(TInt aMaxBits) sl@0: { sl@0: CBitset* self=CBitset::NewLC(aMaxBits); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CBitset* CBitset::NewLC(const CBitset& aSource) sl@0: { sl@0: CBitset* self = new (ELeave) CBitset(aSource); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aSource); sl@0: return self; sl@0: } sl@0: sl@0: EXPORT_C CBitset* CBitset::NewL(const CBitset& aSource) sl@0: { sl@0: CBitset* self=CBitset::NewLC(aSource); sl@0: CleanupStack::Pop(self); sl@0: return self; sl@0: } sl@0: sl@0: CBitset::~CBitset() sl@0: { sl@0: delete [] iBitSet; sl@0: } sl@0: sl@0: CBitset::CBitset() sl@0: { sl@0: } sl@0: sl@0: CBitset::CBitset(const CBitset& aSource) sl@0: : iWidth(aSource.iWidth), iMaxBits(aSource.iMaxBits) sl@0: { sl@0: } sl@0: sl@0: void CBitset::IdentifyBit(TInt aBitId, // in sl@0: TInt &aByte, // out sl@0: TInt &aBitInByte) const // out sl@0: { sl@0: // Identify the byte & bit corresponding to the Id sl@0: aByte = aBitId / 8; sl@0: aBitInByte = aBitId % 8; sl@0: } sl@0: sl@0: EXPORT_C void CBitset::Invert() sl@0: { sl@0: // Invert array sl@0: for (TInt j = 0; j < iWidth ; j++) sl@0: { sl@0: iBitSet[j] = static_cast (~iBitSet[j]); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C TInt CBitset::MaxBits() const sl@0: { sl@0: return iMaxBits; sl@0: } sl@0: sl@0: EXPORT_C void CBitset::Set(TInt aBit) sl@0: { sl@0: __ASSERT_ALWAYS(ValidBit(aBit), User::Panic(KCafUtilsPanic, EInvalidBit)); sl@0: sl@0: TInt targetByte; sl@0: TInt targetBit; sl@0: IdentifyBit(aBit, targetByte, targetBit); sl@0: sl@0: // Or-in the relevant bit sl@0: iBitSet[targetByte] |= (1 << targetBit); sl@0: } sl@0: sl@0: EXPORT_C void CBitset::Unset(TInt aBit) sl@0: { sl@0: __ASSERT_ALWAYS(ValidBit(aBit), User::Panic(KCafUtilsPanic, EInvalidBit)); sl@0: TInt targetByte; sl@0: TInt targetBit; sl@0: IdentifyBit(aBit, targetByte, targetBit); sl@0: sl@0: // And-in NOT(the relevant bit) sl@0: iBitSet[targetByte] &= ~(1 << targetBit); sl@0: } sl@0: sl@0: EXPORT_C TBool CBitset::IsSet(TInt aBit) const sl@0: { sl@0: __ASSERT_ALWAYS(ValidBit(aBit), User::Panic(KCafUtilsPanic, EInvalidBit)); sl@0: sl@0: TInt targetByte; sl@0: TInt targetBit; sl@0: IdentifyBit(aBit, targetByte, targetBit); sl@0: sl@0: // And-in the relevant bit and test for non-zero sl@0: if (iBitSet[targetByte] & (1 << targetBit)) sl@0: { sl@0: return(ETrue); sl@0: } sl@0: else sl@0: { sl@0: return(EFalse); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void CBitset::Reset() sl@0: { sl@0: // Reset the array sl@0: Mem::FillZ(iBitSet, iWidth); sl@0: } sl@0: sl@0: EXPORT_C void CBitset::SetAll() sl@0: { sl@0: Mem::Fill(iBitSet, iWidth, 0xFF); sl@0: } sl@0: sl@0: void CBitset::ConstructL(TInt aMaxBits) sl@0: { sl@0: // Calculate the required number of bytes sl@0: iMaxBits = aMaxBits; sl@0: iWidth = 1 + aMaxBits / 8; sl@0: sl@0: iBitSet = new (ELeave) TUint8[iWidth]; sl@0: Reset(); // Zero the set sl@0: } sl@0: sl@0: void CBitset::ConstructL(const CBitset& aSource) sl@0: { sl@0: // Copy the bits of the source sl@0: iBitSet = new (ELeave) TUint8[iWidth]; sl@0: Mem::Copy(iBitSet, aSource.iBitSet, iWidth); sl@0: } sl@0: sl@0: EXPORT_C void CBitset::ExternalizeL(RWriteStream& aStream) const sl@0: { sl@0: // Write the max-Id sl@0: aStream.WriteInt32L(iMaxBits); sl@0: // Create a descriptor to encapsulate the set sl@0: TPtrC8 ptr(iBitSet, iWidth); sl@0: // Write the descriptor sl@0: aStream.WriteL(ptr); sl@0: } sl@0: sl@0: EXPORT_C void CBitset::InternalizeL(RReadStream& aStream) sl@0: { sl@0: // Delete the array sl@0: delete [] iBitSet; sl@0: iBitSet = NULL; // safety sl@0: // Call the constructor with the max-Id value sl@0: ConstructL(aStream.ReadInt32L()); sl@0: // Create a descriptor to encapsulate the set sl@0: TPtr8 ptr(iBitSet, 0, iWidth); sl@0: // Load into the descriptor sl@0: aStream.ReadL(ptr); sl@0: } sl@0: sl@0: // sl@0: // NB: leavescan will complain that this method calls a leaving sl@0: // function. The Leave is properly documented in the header sl@0: // file. Other than that, not much can be done, especially this sl@0: // class has already been deprecated. sl@0: EXPORT_C CBitset& CBitset::operator=(const CBitset& aSource) sl@0: { sl@0: // avoid self-assignment sl@0: if (this == &aSource) sl@0: { sl@0: return *this; sl@0: } sl@0: sl@0: // check for source/dest size mismatch sl@0: if (aSource.iWidth != iWidth) sl@0: { sl@0: // always use largest width sl@0: TInt widest = iWidth; sl@0: if (widest < aSource.iWidth) sl@0: { sl@0: widest = aSource.iWidth; sl@0: } sl@0: sl@0: // Malloc the desired width sl@0: TUint8 *temp = (TUint8 *) new (ELeave) TUint8[widest]; sl@0: sl@0: // And zero sl@0: Mem::FillZ(temp, widest); sl@0: sl@0: // Now it is safe to re-assign the set sl@0: delete [] iBitSet; sl@0: iBitSet = temp; sl@0: iWidth = widest; sl@0: } sl@0: sl@0: // Width may be the same, but the Max-Id may not, so sl@0: // align these here sl@0: iMaxBits = aSource.iMaxBits; sl@0: sl@0: // Based on the source-size, copy the bitset sl@0: Mem::Copy(iBitSet, aSource.iBitSet, aSource.iWidth); sl@0: sl@0: return *this; sl@0: } sl@0: sl@0: EXPORT_C TBool CBitset::operator==(const CBitset& aSource) const sl@0: { sl@0: TBool result = ETrue; sl@0: if (this == &aSource) sl@0: { sl@0: return ETrue; sl@0: } sl@0: TInt narrowest = iMaxBits; sl@0: if (narrowest > aSource.iMaxBits) sl@0: { sl@0: narrowest = aSource.iMaxBits; sl@0: } sl@0: sl@0: // Compare the first "narrowest/8" bytes - if the result is non-zero, sl@0: // then they are not equal sl@0: if (Mem::Compare(iBitSet, narrowest/8, aSource.iBitSet, narrowest/8)) sl@0: { sl@0: return EFalse; sl@0: } sl@0: sl@0: // Now, compare the last set of bits manually sl@0: for (TInt i = narrowest/8 * 8; i < narrowest; ++i) sl@0: { sl@0: // Comparison of booleans - compare their negations sl@0: if (!IsSet(i) != !aSource.IsSet(i)) sl@0: { sl@0: return EFalse; sl@0: } sl@0: } sl@0: sl@0: return result; sl@0: } sl@0: sl@0: EXPORT_C void CBitset::SetListL(TInt aItems, ...) sl@0: { sl@0: va_list ap; sl@0: va_start(ap, aItems); sl@0: sl@0: // Create a new set (of identical size) sl@0: CBitset *tempSet = CBitset::NewLC(iMaxBits); sl@0: sl@0: // Duplicate this into temporary bitset sl@0: *tempSet = *this; sl@0: sl@0: for (TInt i = 0; i < aItems; i++) sl@0: { sl@0: TInt x = va_arg(ap, TInt); sl@0: tempSet->Set(x); sl@0: } sl@0: sl@0: // No failure, so copy back into this sl@0: *this = *tempSet; sl@0: va_end(ap); sl@0: sl@0: CleanupStack::Pop(tempSet); sl@0: delete tempSet; sl@0: } sl@0: sl@0: EXPORT_C TBool CBitset::IsSetList(TInt aItems, ...) const sl@0: { sl@0: va_list ap; sl@0: va_start(ap, aItems); sl@0: sl@0: for (TInt i = 0; i < aItems; i++) sl@0: { sl@0: TInt x = va_arg(ap, TInt); sl@0: if (!IsSet(x)) sl@0: { sl@0: return (EFalse); sl@0: } sl@0: } sl@0: va_end(ap); sl@0: return (ETrue); sl@0: } sl@0: sl@0: #endif // #ifndef REMOVE_CAF1