syncmlfw/ds/dsutils/changefinder/src/nsmlchangefinder.cpp
changeset 0 b497e44ab2fc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/syncmlfw/ds/dsutils/changefinder/src/nsmlchangefinder.cpp	Thu Dec 17 09:07:52 2009 +0200
@@ -0,0 +1,526 @@
+/*
+* Copyright (c) 2005 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:  Sources
+*
+*/
+
+
+// INCLUDE FILES
+#include <s32strm.h>
+
+#include <nsmldebug.h>
+#include <nsmlchangefinder.h>
+
+#ifndef __WINS__
+// This lowers the unnecessary compiler warning (armv5) to remark.
+// "Warning:  #174-D: expression has no effect..." is caused by 
+// DBG_ARGS8 macro in no-debug builds.
+#pragma diag_remark 174
+#endif
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CNSmlChangeFinder* CNSmlChangeFinder::NewL( MSmlSyncRelationship& aSyncRelationship, TKeyArrayFix aKey, TBool& aHasHistory, TInt aStreamUid )
+	{
+	_DBG_FILE("CNSmlChangeFinder::NewL(): begin");
+	CNSmlChangeFinder* self = new (ELeave) CNSmlChangeFinder(aSyncRelationship, aKey, aStreamUid);
+	CleanupStack::PushL(self);
+	self->ConstructL( aHasHistory );
+	CleanupStack::Pop(); // self
+	_DBG_FILE("CNSmlChangeFinder::NewL(): end");
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::CNSmlChangeFinder
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+CNSmlChangeFinder::CNSmlChangeFinder( MSmlSyncRelationship& aSyncRelationship, TKeyArrayFix aKey, TInt aStreamUid ) : iSyncRelationship(aSyncRelationship), iKey(aKey), iStreamUid(aStreamUid)
+	{
+	_DBG_FILE("CNSmlChangeFinder::CNSmlChangeFinder(): begin");
+	_DBG_FILE("CNSmlChangeFinder::CNSmlChangeFinder(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::ConstructL
+// Symbian 2nd phase constructor.
+// -----------------------------------------------------------------------------
+//
+void CNSmlChangeFinder::ConstructL( TBool& aHasHistory )
+	{
+	_DBG_FILE("CNSmlChangeFinder::ConstructL(): begin");
+	iOldSnapshot = new (ELeave) CArrayFixSeg<TNSmlSnapshotItem>(sizeof(TNSmlSnapshotItem));
+	iCurrentSnapshot = new (ELeave) CArrayFixSeg<TNSmlSnapshotItem>(sizeof(TNSmlSnapshotItem));
+	TUid uid = {iStreamUid};
+	iDataStoreUid = KErrNotFound;
+		
+	aHasHistory = iSyncRelationship.IsStreamPresentL(uid);
+	
+	if (aHasHistory)
+	    {
+	    // Open stream for reading
+	    RReadStream readStream;
+        iSyncRelationship.OpenReadStreamLC(readStream, uid);
+        
+        // Read snapshot from the stream
+        TNSmlSnapshotItem item;
+        TInt itemCount(readStream.ReadInt32L());
+        for (TInt i = 0; i < itemCount; ++i)
+            {
+            readStream >> item;
+            iOldSnapshot->InsertIsqL(item, iKey);
+            }
+            
+        // Read store UID from the stream
+        readStream.ReadL( ( TUint8* ) &iDataStoreUid, 8 );
+        iOldSnapshot->Compress();
+        
+        CleanupStack::PopAndDestroy(); // readStream
+	    }
+	
+	
+	_DBG_FILE("CNSmlChangeFinder::ConstructL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::~CNSmlChangeFinder
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CNSmlChangeFinder::~CNSmlChangeFinder()
+	{
+	_DBG_FILE("CNSmlChangeFinder::~CNSmlChangeFinder(): begin");
+	delete iOldSnapshot;
+	delete iCurrentSnapshot;
+	_DBG_FILE("CNSmlChangeFinder::~CNSmlChangeFinder(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::CloseL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::CloseL()
+	{
+	_DBG_FILE("CNSmlChangeFinder::CloseL(): begin");
+		
+	TUid uid = {iStreamUid};
+	RWriteStream writeStream;
+	
+	// Open stream for writing
+    iSyncRelationship.OpenWriteStreamLC(writeStream, uid);
+	
+	// Write the snapshot to the stream
+    TInt itemCount = iOldSnapshot->Count();
+    writeStream.WriteInt32L(itemCount);
+    for (TInt i = 0; i < itemCount; ++i)
+        {
+        writeStream << iOldSnapshot->At(i);
+        }
+        
+    // Write store UID to the stream
+    writeStream.WriteL( ( TUint8* ) &iDataStoreUid, 8 );
+    writeStream.CommitL();
+    
+    CleanupStack::PopAndDestroy(); // writeStream
+	
+	_DBG_FILE("CNSmlChangeFinder::CloseL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::ResetL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::ResetL()
+	{
+	_DBG_FILE("CNSmlChangeFinder::ResetL(): begin");
+	iOldSnapshot->Reset();
+	if ( iCurrentSnapshot )
+		{
+		iCurrentSnapshot->Reset();
+		}
+
+    // When called after reseting old snapshot, CloseL() externalizes the empty snaphot
+    // to used stream.
+    CloseL();
+    	
+	_DBG_FILE("CNSmlChangeFinder::ResetL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::FindChangedItemsL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::FindChangedItemsL( CNSmlDataItemUidSet& aChangedUids )
+	{
+	_DBG_FILE("CNSmlChangeFinder::FindChangedItemsL(): begin");
+	TNSmlSnapshotItem current;
+	TInt index;
+
+	aChangedUids.Reset();
+	for ( TInt i = 0; i < iCurrentSnapshot->Count(); i++ )
+		{
+		current = iCurrentSnapshot->At(i);
+
+		// Is this also found in old snapshot?
+		if ( !iOldSnapshot->FindIsq(current, iKey, index) )
+			{
+			// It is -> has it been changed?
+			TNSmlSnapshotItem old = iOldSnapshot->At(index);
+			if ( current.Compare(old) > 0 && current.SoftDelete() == EFalse )
+				{
+				// Yep -> add to list
+				User::LeaveIfError(aChangedUids.AddItem(current.ItemId()));
+				}
+			}
+		}
+
+	DBG_ARGS(_S("CNSmlChangeFinder::FindChangedItemsL(): Number of changes = %d"), aChangedUids.ItemCount());
+
+	_DBG_FILE("CNSmlChangeFinder::FindChangedItemsL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::FindDeletedItemsL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::FindDeletedItemsL( CNSmlDataItemUidSet& aDeletedUids )
+	{
+	_DBG_FILE("CNSmlChangeFinder::FindDeletedItemsL(): begin");
+	TNSmlSnapshotItem old;
+	TInt index;
+	
+	aDeletedUids.Reset();
+	for ( TInt i = 0; i < iOldSnapshot->Count(); i++ )
+		{
+		old = iOldSnapshot->At(i);
+		// Does this old item appear in current snapshot?
+		if ( iCurrentSnapshot->FindIsq(old, iKey, index) )
+			{
+			// No -> add to list
+			User::LeaveIfError(aDeletedUids.AddItem(old.ItemId()));
+			}
+		}
+	
+	DBG_ARGS(_S("CNSmlChangeFinder::FindDeletedItemsL(): Number of changes = %d"), aDeletedUids.ItemCount());
+
+	_DBG_FILE("CNSmlChangeFinder::FindDeletedItemsL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::FindNewItems
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::FindNewItemsL( CNSmlDataItemUidSet& aNewUids )
+	{
+	_DBG_FILE("CNSmlChangeFinder::FindNewItemsL(): begin");
+	TNSmlSnapshotItem current;
+	TInt index;
+
+	aNewUids.Reset();
+	for ( TInt i = 0; i < iCurrentSnapshot->Count(); i++ )
+		{
+		current = iCurrentSnapshot->At(i);
+		
+		// Is this also found in old snapshot?
+		if ( iOldSnapshot->FindIsq(current, iKey, index) )
+			{
+			// No -> add to list
+			User::LeaveIfError(aNewUids.AddItem(current.ItemId()));
+			}
+		}
+
+	DBG_ARGS(_S("CNSmlChangeFinder::FindNewItemsL(): Number of changes = %d"), aNewUids.ItemCount());
+	
+	_DBG_FILE("CNSmlChangeFinder::FindNewItemsL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::FindMovedItemsL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::FindMovedItemsL( CNSmlDataItemUidSet& aMovedUids )
+	{
+	_DBG_FILE("CNSmlChangeFinder::FindMovedItemsL(): begin");
+	TNSmlSnapshotItem current;
+	TInt index;
+
+	aMovedUids.Reset();
+	
+	for ( TInt i = 0; i < iCurrentSnapshot->Count(); i++ )
+		{
+		current = iCurrentSnapshot->At(i);
+
+		// Is this also found in old snapshot?
+		if ( !iOldSnapshot->FindIsq(current, iKey, index) )
+			{
+			// It is -> has it been changed?
+			TNSmlSnapshotItem old = iOldSnapshot->At(index);
+			if ( current.Compare(old) == 0 && current.ParentId() != old.ParentId() )
+				{
+				// Yep -> add to list
+				User::LeaveIfError(aMovedUids.AddItem(current.ItemId()));
+				}
+			}
+		}
+
+	DBG_ARGS(_S("CNSmlChangeFinder::FindMovedItemsL(): Number of changes = %d"), aMovedUids.ItemCount());
+
+	_DBG_FILE("CNSmlChangeFinder::FindMovedItemsL(): end");
+	}
+	
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::FindSoftDeletedItemsL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::FindSoftDeletedItemsL( CNSmlDataItemUidSet& aSoftDeletedUids )
+	{
+	_DBG_FILE("CNSmlChangeFinder::FindSoftDeletedItemsL(): begin");
+	TNSmlSnapshotItem current;
+	TInt index;
+
+	aSoftDeletedUids.Reset();
+	
+	for ( TInt i = 0; i < iCurrentSnapshot->Count(); i++ )
+		{
+		current = iCurrentSnapshot->At(i);
+
+		// Is this also found in old snapshot?
+		if ( !iOldSnapshot->FindIsq(current, iKey, index) )
+			{
+			// It is -> has it been changed?
+			TNSmlSnapshotItem old = iOldSnapshot->At(index);
+			if ( current.SoftDelete() && !old.SoftDelete() )
+				{
+				// Yes -> add to list
+				User::LeaveIfError(aSoftDeletedUids.AddItem(current.ItemId()));
+				}
+			}
+		}
+
+	DBG_ARGS(_S("CNSmlChangeFinder::FindSoftDeletedItemsL(): Number of changes = %d"), aSoftDeletedUids.ItemCount());
+
+	_DBG_FILE("CNSmlChangeFinder::FindSoftDeletedItemsL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::ItemAddedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::ItemAddedL( const TNSmlSnapshotItem& aItem )
+	{
+	_DBG_FILE("CNSmlChangeFinder::ItemAddedL(): begin");
+	iOldSnapshot->InsertIsqL(aItem, iKey);
+	iOldSnapshot->Compress();
+	_DBG_FILE("CNSmlChangeFinder::ItemAddedL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::ItemDeleted
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::ItemDeleted( const TNSmlSnapshotItem& aItem )
+	{
+	_DBG_FILE("CNSmlChangeFinder::ItemDeleted(): begin");
+	TInt index;
+	if ( !iOldSnapshot->FindIsq(aItem, iKey, index) )
+		{
+		iOldSnapshot->Delete(index);
+		iOldSnapshot->Compress();
+		}
+	_DBG_FILE("CNSmlChangeFinder::ItemDeleted(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::ItemUpdatedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::ItemUpdatedL( const TNSmlSnapshotItem& aItem )
+	{
+	_DBG_FILE("CNSmlChangeFinder::ItemUpdatedL(): begin");
+	TInt index;
+	if ( !iOldSnapshot->FindIsq(aItem, iKey, index) )
+		{
+		iOldSnapshot->At(index) = aItem;
+		}
+	else
+		{
+		iOldSnapshot->InsertIsqL(aItem, iKey);
+		iOldSnapshot->Compress();
+		}
+	_DBG_FILE("CNSmlChangeFinder::ItemUpdatedL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::ItemMovedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::ItemMovedL( const TNSmlSnapshotItem& aItem )
+	{
+	_DBG_FILE("CNSmlChangeFinder::ItemMovedL(): begin");
+	TInt index;
+	if ( !iOldSnapshot->FindIsq(aItem, iKey, index) )
+		{
+		iOldSnapshot->At(index) = aItem;
+		}
+	else
+		{
+		iOldSnapshot->InsertIsqL(aItem, iKey);
+		iOldSnapshot->Compress();
+		}
+	_DBG_FILE("CNSmlChangeFinder::ItemMovedL(): end");
+	}
+	
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::ItemSoftDeletedL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::ItemSoftDeletedL( const TNSmlSnapshotItem& aItem )
+	{
+	_DBG_FILE("CNSmlChangeFinder::ItemSoftDeletedL(): begin");
+	TInt index;
+	if ( !iOldSnapshot->FindIsq(aItem, iKey, index) )
+		{
+		iOldSnapshot->At(index) = aItem;
+		}
+	else
+		{
+		iOldSnapshot->InsertIsqL(aItem, iKey);
+		iOldSnapshot->Compress();
+		}
+	_DBG_FILE("CNSmlChangeFinder::ItemSoftDeletedL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::CommitChangesL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::CommitChangesL()
+	{
+	_DBG_FILE("CNSmlChangeFinder::CommitChangesL(): begin");
+	iOldSnapshot->Reset();
+	for ( TInt i = 0; i < iCurrentSnapshot->Count(); i++ )
+		{
+		iOldSnapshot->InsertIsqL( iCurrentSnapshot->At( i ), iKey );
+		}
+	_DBG_FILE("CNSmlChangeFinder::CommitChangesL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::CommitChangesL
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::CommitChangesL( const MSmlDataItemUidSet& aUids )
+	{
+	_DBG_FILE("CNSmlChangeFinder::CommitChangesL(): begin");
+	
+	for ( TInt i = 0; i < aUids.ItemCount(); i++ )
+		{
+		TSmlDbItemUid itemId = aUids.ItemAt( i );
+		TNSmlSnapshotItem temp( itemId );
+		TInt indexOld( -1 );
+		TInt indexNew( -1 );
+		if ( !iOldSnapshot->FindIsq( temp, iKey, indexOld) )
+			{
+			if ( !iCurrentSnapshot->FindIsq(temp, iKey, indexNew) )
+				{
+				// Replace, moved or softdeleted
+				iOldSnapshot->At(indexOld) = iCurrentSnapshot->At( indexNew );
+				}
+			else
+				{
+				// Delete
+				iOldSnapshot->Delete(indexOld);
+				}
+			}
+		else
+			{
+			// Add
+			if ( !iCurrentSnapshot->FindIsq(temp, iKey, indexNew) )
+			    {
+			    iOldSnapshot->InsertIsqL( iCurrentSnapshot->At( indexNew ), iKey );
+			    }
+			}
+		}
+	_DBG_FILE("CNSmlChangeFinder::CommitChangesL(): end");
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::SetNewSnapshot
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::SetNewSnapshot( CArrayFixSeg<TNSmlSnapshotItem>* aNewSnapshot )
+	{
+	_DBG_FILE("CNSmlChangeFinder::SetNewSnapshot(): begin");
+#ifdef __NSML_DEBUG__
+	_DBG_FILE("CNSmlChangeFinder::SetNewSnapshot(): old snapshot");
+	TNSmlSnapshotItem item;
+	TInt i;
+
+	for ( i = 0; i < iOldSnapshot->Count(); i++ )
+		{
+		TBuf8<80> b;
+		item = iOldSnapshot->At(i);
+		b = _L8("UID = ");
+		b.AppendNum( item.ItemId() );
+		b.Append(_L8(" LastMod(as Int64) = "));
+		b.AppendNum(item.LastChangedDate().Int64());
+		_DBG_FILE(b.PtrZ());
+		}
+
+	_DBG_FILE("CNSmlChangeFinder::SetNewSnapshot(): new snapshot");
+	for ( i = 0; i < aNewSnapshot->Count(); i++ )
+		{
+		TBuf8<80> b;
+		item = aNewSnapshot->At(i);
+		b = _L8("UID = ");
+		b.AppendNum( item.ItemId() );
+		b.Append(_L8(" LastMod(as Int64) = "));
+		b.AppendNum(item.LastChangedDate().Int64());
+		_DBG_FILE(b.PtrZ());
+		}
+#endif //__NSML_DEBUG__
+	delete iCurrentSnapshot;
+	iCurrentSnapshot = aNewSnapshot;
+	_DBG_FILE("CNSmlChangeFinder::SetNewSnapshot(): end");
+	}
+	
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::DataStoreUid
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt64 CNSmlChangeFinder::DataStoreUid() const
+	{
+	_DBG_FILE("CNSmlChangeFinder::DataStoreUid(): begin");
+	_DBG_FILE("CNSmlChangeFinder::DataStoreUid(): end");
+	return iDataStoreUid;
+	}
+
+// -----------------------------------------------------------------------------
+// CNSmlChangeFinder::SetDataStoreUid
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CNSmlChangeFinder::SetDataStoreUid( TInt64 aUid )
+	{
+	_DBG_FILE("CNSmlChangeFinder::SetDataStoreUid(): begin");
+	iDataStoreUid = aUid;
+	_DBG_FILE("CNSmlChangeFinder::SetDataStoreUid(): end");
+	}
+
+
+// End of File