loggingservices/eventlogger/LogCli/src/LogViewWindowFetcher.cpp
changeset 0 08ec8eefde2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loggingservices/eventlogger/LogCli/src/LogViewWindowFetcher.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,183 @@
+// Copyright (c) 2002-2009 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:
+//
+
+#include "LogViewWindowFetcher.h"
+
+// System includes
+#include <s32mem.h>
+
+// User includes
+#include "logservcli.h"
+
+// Constants
+const TInt KLogSizeOfEventGuess = 200;
+const TInt KLogWindowFetchBufferGranularity = KLogSizeOfEventGuess * 2;
+const TInt KLogWindowFetchBufferMinimumBufferSize = 4;
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// -----> CLogViewWindowFetcher (source)
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CLogViewWindowFetcher::CLogViewWindowFetcher(RLogSession& aSession, TLogViewId aViewId, MLogViewWindowFetcherObserver& aObserver, TInt aPriority)
+:	CActive(aPriority), iSession(aSession), iViewId(aViewId), iObserver(aObserver), iBufferPointer(NULL, 0)
+	{
+	CActiveScheduler::Add(this);
+	iData().iOperationType = ELogOperationViewWindowFetch;
+	}
+
+CLogViewWindowFetcher::~CLogViewWindowFetcher()
+	{
+	Cancel();
+	//
+	delete iBuffer;
+	}
+
+void CLogViewWindowFetcher::ConstructL()
+	{
+	iBuffer = CBufFlat::NewL(KLogWindowFetchBufferGranularity);
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogViewWindowFetcher::PrepareToFetchWindowL(const TLogWindowAndCursor& aRequestedWindow)
+	{
+	iRequestedWindow = aRequestedWindow;
+	iRequestedWindow.iValid = EFalse;
+	iWindowReq = iRequestedWindow; // Initialise window
+	// Setup the buffer so that its the right size to receive the events
+	const TInt range = Max(1, iRequestedWindow.iUpper - iRequestedWindow.iLower + 1);
+	const TInt size = KLogSizeOfEventGuess * range;
+	iBuffer->ResizeL(size);
+	iBufferPointer.Set(iBuffer->Ptr(0));
+	//
+	iFetchWindowData().iBufferSize = size;
+	}
+
+void CLogViewWindowFetcher::Start(TRequestStatus& aObserver)
+	{
+	iObserverRequestStatus = &aObserver;
+	*iObserverRequestStatus = KRequestPending;
+	if	(iRequestedWindow.Range())
+		Fetch(iRequestedWindow);
+	else
+		{
+		// Nothing to fetch
+		iRequestedWindow.NormalizeWindowAndCursor();
+		User::RequestComplete(iObserverRequestStatus, KErrNone);
+		}
+	}
+
+void CLogViewWindowFetcher::SilentCancel()
+	{
+	if	(iObserverRequestStatus)
+		User::RequestComplete(iObserverRequestStatus, KErrNone);
+	Cancel();
+	}
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogViewWindowFetcher::RunL()
+	{
+	const TInt sentByServer = iStatus.Int();
+	User::LeaveIfError(sentByServer);
+	//The server has completed the operation without any error, but there is no returned data
+	//(sentByServer == 0). Then the client has to check if iFetchWindowData().iServerDataSize
+	//data member is set, which means that the server wants to send more data than the client
+	//side buffer can accept. The client has to increase the buffer size and then execute 
+	//the operation again.
+	TInt newSize = iFetchWindowData().iServerDataSize;
+	//newSize was initialized, so iFetchWindowData().iServerDataSize can be set to 0.
+	iFetchWindowData().iServerDataSize = 0;
+	if(sentByServer == 0 && newSize > 0)
+		{
+		iBuffer->ResizeL(newSize);
+		iBufferPointer.Set(iBuffer->Ptr(0));
+		iFetchWindowData().iBufferSize = newSize;
+		//The operation will be executed again later - see "Fetch(iWindowReq)" call.
+		}
+	RBufReadStream stream(*iBuffer);
+	for(TInt i=0; i<sentByServer; i++)
+		{
+		// Give the event to the observer
+		CLogEvent* event = CLogEvent::NewL();
+		CleanupStack::PushL(event);
+		//
+		stream >> *event;
+		iObserver.HandleFetchedWindowItemL(i, event);
+		CleanupStack::Pop(event);
+		}
+
+	// Do we need to fetch the next batch?
+	iWindowReq.iLower += sentByServer; // the lower array index for next request
+
+	if(iWindowReq.iLower <= iWindowReq.iUpper)
+		{
+		// Fetch some more
+		Fetch(iWindowReq);
+		}
+	else
+		{
+		// All done?
+		iBuffer->ResizeL(KLogWindowFetchBufferMinimumBufferSize);
+		iRequestedWindow.iValid = ETrue;
+		CompleteObserver(KErrNone);
+		}
+	}
+
+void CLogViewWindowFetcher::DoCancel()
+	{
+	if	(iData().iOperationId > 0)
+		{
+		const TInt errorIgnored = iSession.Send(ELogOperationCancel, TIpcArgs(&iData));
+		(void) errorIgnored;
+		//
+		iData().iOperationId = KLogNullOperationId;
+		}
+
+	CompleteObserver(KErrCancel);
+	}
+
+TInt CLogViewWindowFetcher::RunError(TInt aError)
+	{
+	CompleteObserver(aError);
+	return KErrNone;
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogViewWindowFetcher::Fetch(const TLogWindow& aWindow)
+	{
+	iFetchWindowData().iLower = aWindow.iLower;
+	iFetchWindowData().iUpper = aWindow.iUpper;
+	//
+	iData().iOperationId = iSession.AllocateIdOperation();
+	//
+	iSession.Send(ELogViewOperationInitiate, TIpcArgs(&iData,iViewId,&iFetchWindowData,&iBufferPointer), iStatus);
+	SetActive();
+	}
+
+void CLogViewWindowFetcher::CompleteObserver(TInt aError)
+	{
+	if	(iObserverRequestStatus)
+		User::RequestComplete(iObserverRequestStatus, aError);
+	}