diff -r 000000000000 -r b497e44ab2fc syncmlfw/common/historylog/src/NSmlHistoryArray.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/syncmlfw/common/historylog/src/NSmlHistoryArray.cpp Thu Dec 17 09:07:52 2009 +0200 @@ -0,0 +1,658 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "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: History entry array +* +*/ + + +#include +#include +#include "NSmlHistoryArray.h" + + + +/////////////////////////////////////////////////////////////////////////// + +#ifdef _DEBUG + +#include + +_LIT(KLogFile,"smlsync.txt"); +//_LIT(KLogDirFullName,"c:\\logs\\"); +_LIT(KLogDir,"smlsync"); + +// Declare the FPrint function +inline void FPrint(const TRefByValue aFmt, ...) + { + VA_LIST list; + VA_START(list,aFmt); + RFileLogger::WriteFormat(KLogDir, KLogFile, EFileLoggingModeAppend, aFmt, list); + } + +// =========================================================================== +#ifdef __WINS__ // File logging for WINS +// =========================================================================== +#define FLOG(arg...) { FPrint(arg); } +//#define FLOG(a) { RDebug::Print(a); } +// =========================================================================== +#else // RDebug logging for target HW +// =========================================================================== +#define FLOG(arg...) { FPrint(arg); } +#endif //__WINS__ + + +// =========================================================================== +#else // // No loggings --> Reduced binary size +// =========================================================================== +#define FLOG(arg...) + +#endif // _DEBUG + +///////////////////////////////////////////////////////////////////////////// + + + +// --------------------------------------------------------- +// CNSmlHistoryArray::CNSmlHistoryArray() +// Two phase constructor +// --------------------------------------------------------- +EXPORT_C CNSmlHistoryArray* CNSmlHistoryArray::NewL() + { + CNSmlHistoryArray* self = new (ELeave) CNSmlHistoryArray; + return self; + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::CNSmlHistoryArray() +// Constructor +// --------------------------------------------------------- +CNSmlHistoryArray::CNSmlHistoryArray() +: iHistoryOwned(EFalse), iSortOrder(CSyncMLHistoryEntry::ESortByTime) + { + + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::CNSmlHistoryArray() +// Destructor +// --------------------------------------------------------- +EXPORT_C CNSmlHistoryArray::~CNSmlHistoryArray() + { + DeleteAllEntries(); + iHistory.Close(); + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::Count() +// Returns the item count +// --------------------------------------------------------- +EXPORT_C TInt CNSmlHistoryArray::Count() + { + return iHistory.Count(); + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::AppendEntryL(CSyncMLHistoryEntry* aEntry) +// Appends new entry to history array and removes the oldest item +// if more than five items would be in the array +// --------------------------------------------------------- +EXPORT_C void CNSmlHistoryArray::AppendEntryL(CSyncMLHistoryEntry* aEntry) + { + if ( aEntry ) + { + ResetCorruptedHistroy () ; + if ( aEntry->EntryType().iUid == KSmlHistoryEntryJobTypeValue ) + { + DoJobLimitCheck(); + } + else + { + DoPushMsgLimitCheck(); + } + + iHistory.AppendL( aEntry ); + } + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::ResetCorruptedHistroy() +// This function will reset the history if it is corrupted +// --------------------------------------------------------- + +void CNSmlHistoryArray::ResetCorruptedHistroy () +{ + TTime earliest; + earliest.UniversalTime(); + TTime historyTime; + if (iHistory.Count() >= 1) + { + SortEntries(CSyncMLHistoryEntry::ESortByTime); + historyTime = iHistory[iHistory.Count() - 1]->TimeStamp() ; + if (historyTime > earliest ) + { + DeleteAllEntries() ; + } + } +} + +// --------------------------------------------------------- +// CNSmlHistoryArray::RemoveEntry(TInt aIndex) +// Removes entry from specified index +// --------------------------------------------------------- +EXPORT_C CSyncMLHistoryEntry* CNSmlHistoryArray::RemoveEntry(TInt aIndex) + { + if ( (aIndex >= 0 ) && ( aIndex < iHistory.Count() ) ) + { + CSyncMLHistoryEntry* entry = iHistory[aIndex]; + iHistory.Remove(aIndex); + return entry; + } + return NULL; + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::DeleteAllEntriesL() +// Deletes all entries from the array +// --------------------------------------------------------- +EXPORT_C void CNSmlHistoryArray::DeleteAllEntries() + { + if (iHistoryOwned) + { + iHistory.ResetAndDestroy(); + } + else + { + iHistory.Reset(); + } + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::DeleteAllEntriesL() +// Returns the entry from specified index +// --------------------------------------------------------- +EXPORT_C CSyncMLHistoryEntry& CNSmlHistoryArray::Entry(TInt aIndex) + { + return *iHistory[aIndex]; + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::SortEntries(CSyncMLHistoryEntry::TSortOrder aSortType) +// Sorts the array using specified sort type +// --------------------------------------------------------- +EXPORT_C void CNSmlHistoryArray::SortEntries(CSyncMLHistoryEntry::TSortOrder aSortType) + { + if ( aSortType == CSyncMLHistoryEntry::ESortByTime ) + { + TLinearOrder sort( CNSmlHistoryArray::SortByTime ); + iHistory.Sort( sort ); + } + else + { + TLinearOrder sort( CNSmlHistoryArray::SortByType ); + iHistory.Sort( sort ); + } + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::SetOwnerShip(TBool aOwner) +// Changes the ownership of items. If ETrue array takes ownership. +// --------------------------------------------------------- +EXPORT_C void CNSmlHistoryArray::SetOwnerShip(TBool aOwner) + { + iHistoryOwned = aOwner; + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::InternalizeL(RReadStream& aStream) +// Reads history array from given stream +// --------------------------------------------------------- +EXPORT_C void CNSmlHistoryArray::InternalizeL(RReadStream& aStream) + { + DeleteAllEntries(); + TInt count = aStream.ReadInt32L(); + + for (TInt i = 0; i < count; i++) + { + CSyncMLHistoryEntry* entry = CSyncMLHistoryEntry::NewL(aStream); + iHistory.AppendL(entry); + } + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::ExternalizeL(RWriteStream& aStream) const +// Writes history array to given stream +// --------------------------------------------------------- +EXPORT_C void CNSmlHistoryArray::ExternalizeL(RWriteStream& aStream) const + { + TInt count = iHistory.Count(); + aStream.WriteInt32L(count); + for (TInt i = 0; i < count; i++) + { + iHistory[i]->ExternalizeL(aStream); + } + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::DoJobLimitCheck() +// Limits the amount of CSyncMLHistoryJobs. Oldest is removed. +// --------------------------------------------------------- +void CNSmlHistoryArray::DoJobLimitCheck() + { + RemoveHistoryJob(); + + /* + TInt count(0); + TInt target(-1); + TTime earliest; + + earliest.UniversalTime(); + + for (TInt index = 0; index < iHistory.Count(); index++) + { + if ( iHistory[index]->EntryType().iUid == KSmlHistoryEntryJobTypeValue ) + { + if (iHistory[index]->TimeStamp() < earliest ) + { + earliest = iHistory[index]->TimeStamp(); + target = index; + } + count++; + } + } + + if (count > KNSmlMaxHistoryLogEntries) + { + delete RemoveEntry(target); + } + */ + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::DoPushMsgLimitCheck() +// Limits the amount of CSyncMLHistoryPushMsg. Oldest is removed. +// --------------------------------------------------------- +void CNSmlHistoryArray::DoPushMsgLimitCheck() + { + TInt count(0); + TInt target(-1); + TTime earliest; + + earliest.UniversalTime(); + + for (TInt index = 0; index < iHistory.Count(); index++) + { + if ( iHistory[index]->EntryType().iUid == KSmlHistoryEntryPushMsgTypeValue ) + { + if (iHistory[index]->TimeStamp() < earliest ) + { + earliest = iHistory[index]->TimeStamp(); + target = index; + } + count++; + } + } + + if (count > KNSmlMaxHistoryLogEntries) + { + delete RemoveEntry(target); + } + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::SortByType(const CSyncMLHistoryEntry& aLeft, const CSyncMLHistoryEntry& aRight) +// Sorts the array by entry type. +// --------------------------------------------------------- +TInt CNSmlHistoryArray::SortByType(const CSyncMLHistoryEntry& aLeft, const CSyncMLHistoryEntry& aRight) + { + TInt left = aLeft.EntryType().iUid; + TInt right = aRight.EntryType().iUid; + + if ( left < right ) + { + return -1; // Compared entry type is smaller + } + + if ( left > right ) + { + return 1; // Compared entry type is bigger + } + + return 0; + } + +// --------------------------------------------------------- +// CNSmlHistoryArray::SortByTime(const CSyncMLHistoryEntry& aLeft, const CSyncMLHistoryEntry& aRight) +// Sorts the array by entrie's timestamp +// --------------------------------------------------------- +TInt CNSmlHistoryArray::SortByTime(const CSyncMLHistoryEntry& aLeft, const CSyncMLHistoryEntry& aRight) + { + + if ( aLeft.TimeStamp() < aRight.TimeStamp() ) + { + return -1; // Compared entry is earlier + } + + if ( aLeft.TimeStamp() > aRight.TimeStamp() ) + { + return 1; // Compared entry is later + } + + return 0; + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::RemoveHistoryJob +// +// --------------------------------------------------------- +void CNSmlHistoryArray::RemoveHistoryJob() + { + TInt err = KErrNone; + + TRAP(err, RemoveHistoryJobL()); + + if (err != KErrNone) + { + FLOG( _L("### CNSmlHistoryArray::RemoveHistoryJob failed (%d) ###"), err ); + } + +#ifdef _DEBUG + TRAP_IGNORE(LogHistoryArrayL()); + CheckHistoryJobCount(); +#endif + + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::RemoveHistoryJobL +// +// This function removes old history job entries from history +// array. If old history job entry contains tasks that do not +// exist in 5 most recent entries, old entry is not removed. +// This way sync information for a task is not lost. +// --------------------------------------------------------- +void CNSmlHistoryArray::RemoveHistoryJobL() + { + RArray taskList; + CleanupClosePushL(taskList); + + for (;;) + { + if (!RemoveHistoryJobL(taskList)) + { + break; + } + } + + CleanupStack::PopAndDestroy(&taskList); + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::RemoveHistoryJobL +// +// --------------------------------------------------------- +TBool CNSmlHistoryArray::RemoveHistoryJobL(RArray& aTaskList) + { + FLOG( _L("CNSmlHistoryArray::RemoveHistoryJobL START") ); + + const TInt KMaxExtraHistoryLogEntries = 5; + const TInt KMaxTotalCount = KNSmlMaxHistoryLogEntries + + KMaxExtraHistoryLogEntries; + + SortEntries(CSyncMLHistoryEntry::ESortByTime); + InitializeTaskListL(aTaskList); + + TInt historyJobCount = 0; + TInt count = iHistory.Count(); + + + // first pass 5 (KNSmlMaxHistoryLogEntries) latest history + // job entries and then check whether possible extra entries + // can be removed + for (TInt i=count-1; i>=0; i--) + { + if (iHistory[i]->EntryType().iUid == KSmlHistoryEntryJobTypeValue) + { + historyJobCount++; + + if (historyJobCount > KNSmlMaxHistoryLogEntries) + { + const CSyncMLHistoryEntry* entry = iHistory[i]; + const CSyncMLHistoryJob* historyJob = + CSyncMLHistoryJob::DynamicCast(entry); + + if (historyJobCount > KMaxTotalCount) + { + // history array is full - delete extra entry + FLOG( _L("### history array overflow - delete extra entry ###") ); + delete RemoveEntry(i); + + FLOG( _L("CNSmlHistoryArray::RemoveHistoryJobL END") ); + return ETrue; + } + + if (CanRemove(historyJob, aTaskList)) + { + FLOG(_L("remove history job entry")); +#ifdef _DEBUG + LogHistoryJobL(historyJob); +#endif + delete RemoveEntry(i); + + FLOG( _L("CNSmlHistoryArray::RemoveHistoryJobL END") ); + return ETrue; + } + else + { + FLOG(_L("leave extra history job entry")); +#ifdef _DEBUG + LogHistoryJobL(historyJob); +#endif + + UpdateTaskListL(historyJob, aTaskList); + } + } + } + } + + FLOG( _L("CNSmlHistoryArray::RemoveHistoryJobL END") ); + return EFalse; + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::InitializeTaskListL +// +// --------------------------------------------------------- +void CNSmlHistoryArray::InitializeTaskListL(RArray& aTaskList) + { + aTaskList.Reset(); + TInt historyJobCount = 0; + TInt count = iHistory.Count(); + + // store sync tasks from 5 most recent history job entries + for (TInt i=count-1; i>=0; i--) + { + if (iHistory[i]->EntryType().iUid == KSmlHistoryEntryJobTypeValue) + { + historyJobCount++; + if (historyJobCount <= KNSmlMaxHistoryLogEntries) + { + const CSyncMLHistoryEntry* entry = iHistory[i]; + const CSyncMLHistoryJob* historyJob = + CSyncMLHistoryJob::DynamicCast(entry); + + UpdateTaskListL(historyJob, aTaskList); + } + } + } + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::UpdateTaskListL +// +// --------------------------------------------------------- +void CNSmlHistoryArray::UpdateTaskListL(const CSyncMLHistoryJob* aHistoryJob, + RArray& aTaskList) + { + TInt count = aHistoryJob->TaskCount(); + for (TInt i=0; iTaskAt(i); + if (aTaskList.Find(taskInfo.iTaskId) == KErrNotFound) + { + User::LeaveIfError(aTaskList.Append(taskInfo.iTaskId)); + } + } + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::CanRemove +// +// --------------------------------------------------------- +TBool CNSmlHistoryArray::CanRemove(const CSyncMLHistoryJob* aHistoryJob, + RArray& aTaskList) + { + + // check wheteher this history job has a task that does not + // exist in aTaskList + TInt count = aHistoryJob->TaskCount(); + for (TInt i=0; iTaskAt(i); + + if (aTaskList.Find(taskInfo.iTaskId) == KErrNotFound) + { + return EFalse; + } + } + + return ETrue; + } + + +#ifdef _DEBUG + +// --------------------------------------------------------- +// CNSmlHistoryArray::CheckHistoryJobCount +// +// --------------------------------------------------------- +void CNSmlHistoryArray::CheckHistoryJobCount() + { + _LIT(KPanicCategory,"CNSmlHistoryArray"); + + const TInt KMaxExtraHistoryLogEntries = 5; + TInt limit = KNSmlMaxHistoryLogEntries + KMaxExtraHistoryLogEntries; + + TInt historyJobCount = 0; + TInt count = iHistory.Count(); + + for (TInt i=count-1; i>=0; i--) + { + if (iHistory[i]->EntryType().iUid == KSmlHistoryEntryJobTypeValue) + { + historyJobCount++; + + if (historyJobCount > limit) + { + User::Panic(KPanicCategory, KErrOverflow); + } + } + } + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::LogHistoryJobL +// +// --------------------------------------------------------- +void CNSmlHistoryArray::LogHistoryJobL(const CSyncMLHistoryJob* aHistoryJob) + { + FLOG( _L("---- CSyncMLHistoryJob ----") ); + + TBuf<128> buf1; TBuf<128> buf2; TBuf<128> buf3; + + TTime time = aHistoryJob->TimeStamp(); + GetDateTimeTextL(buf1, time); + buf2.Format(_L("sync time: %S"), &buf1); + FLOG(buf2); + + buf2 = KNullDesC; + TInt count = aHistoryJob->TaskCount(); + for (TInt i=0; iTaskAt(i); + buf3.Format(_L("%d "), taskInfo.iTaskId); + buf2.Append(buf3); + } + + buf1.Format(_L("sync tasks: %S"), &buf2); + FLOG(buf1); + + + FLOG( _L("---- CSyncMLHistoryJob ----") ); + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::LogHistoryArrayL +// +// --------------------------------------------------------- +void CNSmlHistoryArray::LogHistoryArrayL() + { + FLOG( _L("---- history array ----") ); + + TInt historyJobCount = 0; + TInt count = iHistory.Count(); + + SortEntries(CSyncMLHistoryEntry::ESortByTime); + + for (TInt i=count-1; i>=0; i--) + { + if (iHistory[i]->EntryType().iUid == KSmlHistoryEntryJobTypeValue) + { + historyJobCount++; + + const CSyncMLHistoryEntry* entry = iHistory[i]; + const CSyncMLHistoryJob* historyJob = + CSyncMLHistoryJob::DynamicCast(entry); + LogHistoryJobL(historyJob); + } + } + + FLOG( _L("---- history array ----") ); + } + + +// --------------------------------------------------------- +// CNSmlHistoryArray::GetDateTimeTextL +// +// --------------------------------------------------------- +void CNSmlHistoryArray::GetDateTimeTextL(TDes& aText, TTime aDateTime) + { + TDateTime dt = aDateTime.DateTime(); + aText.Format(_L("%02d.%02d.%04d %02d:%02d:%02d"), dt.Day()+1, dt.Month()+1, dt.Year(), dt.Hour(), dt.Minute(), dt.Second()); + } + +#endif + +