loggingservices/eventlogger/LogServ/src/LogServViewWindowFetcher.cpp
changeset 0 08ec8eefde2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/loggingservices/eventlogger/LogServ/src/LogServViewWindowFetcher.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,204 @@
+// 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 "LogServViewWindowFetcher.h"
+#include <s32mem.h>
+#include "LOGGET.H"
+#include "logservpanic.h"
+#include "LogServView.h"
+
+// Constants
+const TInt KLogViewWindowTransferBufferGranularity = 500;
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// -----> CLogServViewWindowFetcher (source)
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CLogServViewWindowFetcher::CLogServViewWindowFetcher(MLogServDatabaseTransactionInterface& aDatabase, TInt aPriority)
+:	CLogActive(aPriority), iDatabase(aDatabase)
+	{
+	}
+
+CLogServViewWindowFetcher::~CLogServViewWindowFetcher()
+	{
+	Cancel();
+	delete iBuffer;
+	delete iGetEvent;
+	delete iEvent;
+	}
+
+void CLogServViewWindowFetcher::ConstructL()
+	{
+	iBuffer = CBufFlat::NewL(KLogViewWindowTransferBufferGranularity);
+	iEvent = CLogEvent::NewL();
+	iGetEvent = CLogGetEvent::NewL(iDatabase, Priority());
+	}
+
+CLogServViewWindowFetcher* CLogServViewWindowFetcher::NewL(MLogServDatabaseTransactionInterface& aDatabase, TInt aPriority)
+	{
+	CLogServViewWindowFetcher* self = new(ELeave) CLogServViewWindowFetcher(aDatabase, aPriority);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServViewWindowFetcher::StartL(TRequestStatus& aStatus, const CLogServViewBase& aView, const TLogTransferWindow& aWindow, const RMessage2& aMessage)
+	{
+	__ASSERT_ALWAYS(iState == EStateIdle, Panic(ELogViewWindowFetcherBadState));
+	//
+	Queue(aStatus);
+	//
+	iView = &aView;
+	iWindow = aWindow;
+	iMessage = &aMessage;
+	iBuffer->Reset();
+	iWindowIndex = 0;
+	iState = EStateStarting;
+	//
+	CompleteRequest();
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServViewWindowFetcher::DoRunL()
+	{
+	const TInt error = iStatus.Int();
+	User::LeaveIfError(error);
+
+	switch(iState)
+		{
+	case EStateStarting:
+		GetNextEventL(iWindowIndex);
+		iState = EStateContinuing;
+		break;
+	case EStateContinuing:
+		ProcessEventL();
+		break;
+	default:
+		__ASSERT_ALWAYS(0, Panic(ELogViewWindowFetcherBadState2));
+		break;
+		}
+	}
+
+void CLogServViewWindowFetcher::ProcessEventL()
+	{
+	// Try and write the event to the buffer
+	const TInt sizeBefore = iBuffer->Size();
+	RBufWriteStream stream(*iBuffer, iBuffer->Size());
+	stream << *iEvent;
+	const TInt sizeAfter = iBuffer->Size();
+	//
+	TBool moreToFetch = EFalse;
+
+	const TInt numberToFetch = iWindow.Range();
+	if	(sizeAfter > iWindow.iBufferSize)
+		{
+		//The client buffer size is too small. It should be increased, if the client wants
+		//to get the server data. 
+		//The server sets iServerDataSize data member with the minimal size which the client
+		//side buffer should have - sizeAfter.
+		TPtrC8 ptr(reinterpret_cast <TUint8*> (&iWindow), sizeof(iWindow));
+		iWindow.iServerDataSize = sizeAfter;
+		iMessage->WriteL(2, ptr);
+
+		iBuffer->ResizeL(sizeBefore);
+		iWindowIndex -= 1; // we didn't get this event
+		}
+	else if	(iWindowIndex+1 < numberToFetch)
+		{
+		GetNextEventL(iWindowIndex+1);
+		moreToFetch = ETrue;
+		}
+	
+	if	(!moreToFetch)
+		{
+		// Write whatever we have back to the client's address space
+		TPtr8 pBuffer(iBuffer->Ptr(0));
+		iMessage->WriteL(3, pBuffer);
+		iState = EStateIdle;
+		}
+	}
+
+void CLogServViewWindowFetcher::DoCancel()
+	{
+	switch(iState)
+		{
+	case EStateStarting:
+		// Nothing to do, completed our own request status
+		break;
+	case EStateContinuing:
+		iGetEvent->Cancel();
+		break;
+	default:
+		__ASSERT_ALWAYS(0, Panic(ELogViewWindowFetcherBadState3));
+		break;
+		}
+	CLogActive::DoCancel();
+	}
+
+void CLogServViewWindowFetcher::DoComplete(TInt& aCompletionCode)
+	{
+	// Indicates to the client side how many records we retrieved.
+	if	(aCompletionCode == KErrNone)
+		aCompletionCode = iWindowIndex+1;
+	else
+		iState = EStateIdle;
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServViewWindowFetcher::GetNextEventL(TInt aWindowIndex)
+	{
+	const TInt index = iWindow.iLower + aWindowIndex;
+	const TInt viewCount = iView->Count();
+	if	(index < 0)
+		{
+		::PanicClientL(*iMessage, ELogViewBadWindow);
+		}
+	else if (index >= viewCount)
+		{
+		// View is still catching up with changes which have been made in the server?
+		CLogEvent* event = CLogEvent::NewL();
+		delete iEvent;
+		iEvent = event;
+		CompleteRequest();
+		iWindowIndex = aWindowIndex;
+		}
+	else
+		{
+		const TLogId id = iView->At(index);
+		iEvent->SetId(id);
+		iGetEvent->StartL(*iEvent, iStatus, *iMessage);
+		iWindowIndex = aWindowIndex;
+		SetActive();
+		}
+	}
+
+void CLogServViewWindowFetcher::CompleteRequest()
+	{
+	TRequestStatus* status = &iStatus;
+	User::RequestComplete(status, KErrNone);
+	SetActive();
+	}