sl@0: // Copyright (c) 2002-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 "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: #include "LogServRecentList.h" sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "logservpanic.h" sl@0: #include "LogServRecentCondition.h" sl@0: #include "LogServSqlStrings.h" sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: // -----> CLogServRecentList (source) sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: CLogServRecentList::~CLogServRecentList() sl@0: { sl@0: iConditions.ResetAndDestroy(); sl@0: iConditions.Close(); sl@0: } sl@0: sl@0: void CLogServRecentList::ConstructL(TResourceReader& aReader) sl@0: { sl@0: iId = static_cast(aReader.ReadInt8()); sl@0: iDuplicates = static_cast(aReader.ReadUint16()); sl@0: sl@0: TInt count = aReader.ReadInt16(); sl@0: iConditions.ReserveL(count); sl@0: while(count--) sl@0: { sl@0: CLogServRecentCondition* condition = CLogServRecentCondition::NewL(aReader); sl@0: TInt err = iConditions.Append(condition); sl@0: __ASSERT_ALWAYS(err == KErrNone, Panic(ELogArrayReserved)); sl@0: } sl@0: } sl@0: sl@0: CLogServRecentList* CLogServRecentList::NewL(TResourceReader& aReader) sl@0: { sl@0: CLogServRecentList* self = new(ELeave) CLogServRecentList; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(aReader); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: #ifdef SYSLIBS_TEST sl@0: sl@0: #pragma BullseyeCoverage off sl@0: sl@0: //Used by the unit tests when SYSLIBS_TEST macro is defined. sl@0: //Creates a complex recent list with a lot of fields. sl@0: //This helps covering most of recent list related production code branches. sl@0: CLogServRecentList* CLogServRecentList::TestNewL() sl@0: { sl@0: CLogServRecentList* self = new(ELeave) CLogServRecentList; sl@0: CleanupStack::PushL(self); sl@0: self->TestConstructL(); sl@0: CleanupStack::Pop(); sl@0: return self; sl@0: } sl@0: sl@0: void CLogServRecentList::TestConstructL() sl@0: { sl@0: iId = KLogRctTListId; sl@0: iDuplicates = ELogRemotePartyField | ELogNumberField | ELogDirectionField | ELogDurationTypeField | sl@0: ELogStatusField | ELogFlagsField | ELogSubjectField sl@0: #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM sl@0: | ELogSimIdField sl@0: #endif sl@0: ; sl@0: TInt count = 7;//7 test recent list conditions added in the code bellow sl@0: iConditions.ReserveL(count); sl@0: //1 sl@0: CLogServRecentCondition* condition1 = CLogServRecentCondition::TestNewL(ELogDirectionField); sl@0: (void)iConditions.Append(condition1); sl@0: //2 sl@0: CLogServRecentCondition* condition2 = CLogServRecentCondition::TestNewL(ELogDurationTypeField); sl@0: (void)iConditions.Append(condition2); sl@0: //3 sl@0: CLogServRecentCondition* condition3 = CLogServRecentCondition::TestNewL(ELogNumberField); sl@0: (void)iConditions.Append(condition3); sl@0: //4 sl@0: CLogServRecentCondition* condition4 = CLogServRecentCondition::TestNewL(ELogRemotePartyField); sl@0: (void)iConditions.Append(condition4); sl@0: //5 sl@0: CLogServRecentCondition* condition5 = CLogServRecentCondition::TestNewL(ELogStatusField); sl@0: (void)iConditions.Append(condition5); sl@0: //6 sl@0: CLogServRecentCondition* condition6 = CLogServRecentCondition::TestNewL(ELogFlagsField); sl@0: (void)iConditions.Append(condition6); sl@0: #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM sl@0: //7 sl@0: CLogServRecentCondition* condition7 = CLogServRecentCondition::TestNewL(ELogSimIdField); sl@0: (void)iConditions.Append(condition7); sl@0: #endif sl@0: } sl@0: sl@0: #pragma BullseyeCoverage on sl@0: sl@0: #endif//SYSLIBS_TEST sl@0: sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: ///////////////////////////////////////////////////////////////////////////////////////// sl@0: sl@0: /** sl@0: Checks whether the aEvent field values satisfy the conditions described in sl@0: in this CLogServRecentList object. sl@0: sl@0: @param aEvent Reference to a CLogEvent object which field values will be tested. sl@0: @return True If the aEvent field values satisfy the conditions, false otherwise. sl@0: */ sl@0: TBool CLogServRecentList::IsRecent(const CLogEvent& aEvent) const sl@0: { sl@0: //The implemented algorithm is: sl@0: // usedFieldBitMask - bit mask, where the "1" bits correspond to the fields used in the "recent condition" objects - sl@0: // the iConditions array. Each "recent condition" object has "field" and "value" data members, sl@0: // where the "field" data member value is a power of 2. sl@0: // Some of the iConditions elemens may have the same field value. sl@0: // matchedFieldBitMask - bit mask, where the "1" bits correspond to a "recent condition" object which field value is sl@0: // equal to the corresponding field value of the aEvent object. sl@0: // sl@0: // For example, the iConditions array contains three elements initialised as: sl@0: // [2, "Incomming"] sl@0: // [8, 1000550D] sl@0: // [2, "Incomming Alternate"] sl@0: // The aEvent object contains these fields initialized: sl@0: // [2, "Incomming"] sl@0: // [8, 1000550D] sl@0: // Then usedFieldBitMask value will be: 0000000A - (2 | 8). sl@0: // matchedFieldBitMask value will be: 0000000A - (2 | 8). sl@0: // So, the operation performed on particular matchedFieldBitMask bit is bitwise OR - sl@0: // in case if two "recent condition" objects use the same field (but have different field values), then the result sl@0: // of the matching operation with the corresponding aEvent field value will be OR-ed in that matchedFieldBitMask bit. sl@0: TUint16 usedFieldBitMask = 0; sl@0: TUint16 matchedFieldBitMask = 0; sl@0: for(TInt i=iConditions.Count()-1;i>=0;--i) sl@0: { sl@0: const CLogServRecentCondition& condition = *iConditions[i]; sl@0: usedFieldBitMask |= condition.Field(); sl@0: if(condition.IsMatch(aEvent)) sl@0: { sl@0: matchedFieldBitMask |= condition.Field(); sl@0: } sl@0: } sl@0: //If both usedFieldBitMask and matchedFieldBitMask are 0, that means - the iConditions array is empty. sl@0: //The function returns true in this case. sl@0: return usedFieldBitMask == matchedFieldBitMask; sl@0: } sl@0: sl@0: void CLogServRecentList::GetFilter(const CLogEvent& aEvent, CLogFilter& aFilter) const sl@0: { sl@0: TUint16 nullFieldsBitMask = 0; sl@0: if (iDuplicates & ELogContactField) sl@0: { sl@0: aFilter.SetContact(aEvent.Contact()); sl@0: if (aEvent.Contact() == KLogNullContactId) sl@0: nullFieldsBitMask |= ELogContactField; sl@0: } sl@0: sl@0: if (iDuplicates & ELogDirectionField) sl@0: { sl@0: aFilter.SetDirection(aEvent.Direction()); sl@0: if (aEvent.Direction().Length() == 0) sl@0: nullFieldsBitMask |= ELogDirectionField; sl@0: } sl@0: sl@0: if (iDuplicates & ELogDurationTypeField) sl@0: { sl@0: aFilter.SetDurationType(aEvent.DurationType()); sl@0: if (aEvent.DurationType() == KLogDurationNone) sl@0: nullFieldsBitMask |= ELogDurationTypeField; sl@0: } sl@0: sl@0: if (iDuplicates & ELogEventTypeField) sl@0: { sl@0: aFilter.SetEventType(aEvent.EventType()); sl@0: if (aEvent.EventType() == KNullUid) sl@0: nullFieldsBitMask |= ELogEventTypeField; sl@0: } sl@0: sl@0: if (iDuplicates & ELogNumberField) sl@0: { sl@0: aFilter.SetNumber(aEvent.Number()); sl@0: if (aEvent.Number().Length() == 0) sl@0: nullFieldsBitMask |= ELogNumberField; sl@0: } sl@0: sl@0: if (iDuplicates & ELogRemotePartyField) sl@0: { sl@0: aFilter.SetRemoteParty(aEvent.RemoteParty()); sl@0: if (aEvent.RemoteParty().Length() == 0) sl@0: nullFieldsBitMask |= ELogRemotePartyField; sl@0: } sl@0: sl@0: if (iDuplicates & ELogStatusField) sl@0: { sl@0: aFilter.SetStatus(aEvent.Status()); sl@0: if (aEvent.Status().Length() == 0) sl@0: nullFieldsBitMask |= ELogStatusField; sl@0: } sl@0: sl@0: if (iDuplicates & ELogFlagsField) sl@0: { sl@0: aFilter.SetFlags(aEvent.Flags()); sl@0: if (aEvent.Flags() == KLogNullFlags) sl@0: nullFieldsBitMask |= ELogFlagsField; sl@0: } sl@0: sl@0: #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM sl@0: if (iDuplicates & ELogSimIdField) sl@0: { sl@0: aFilter.SetSimId(aEvent.SimId()); sl@0: if (aEvent.SimId() == KLogNullSimId) sl@0: nullFieldsBitMask |= ELogSimIdField; sl@0: } sl@0: #endif sl@0: sl@0: aFilter.SetNullFields(nullFieldsBitMask); sl@0: // This is a special case, if all the fields are null sl@0: // In this case we want to be a duplicate of other events where all the fields are null sl@0: if (IsFilterEmpty(aFilter)) sl@0: aFilter.SetNullFields(iDuplicates); sl@0: } sl@0: sl@0: TBool CLogServRecentList::IsFilterEmpty(const CLogFilter& aFilter) const sl@0: { sl@0: return aFilter.EventType() == KNullUid && sl@0: aFilter.RemoteParty().Length() == 0 && sl@0: aFilter.Direction().Length() == 0 && sl@0: aFilter.Status().Length() == 0 && sl@0: aFilter.Contact() == KLogNullContactId && sl@0: aFilter.Number().Length() == 0 sl@0: #ifdef SYMBIAN_ENABLE_EVENTLOGGER_DUALSIM sl@0: && sl@0: aFilter.SimId() == KLogNullSimId sl@0: #endif sl@0: ; sl@0: } sl@0: