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