--- a/devicediagnosticsfw/diagresultsdb/server/src/diagresultsdbsession.cpp Fri May 14 16:42:50 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1042 +0,0 @@
-/*
-* Copyright (c) 2007 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: Class definition of CDiagResultsDbSession
-*
-*/
-
-
-#include "diagresultsdatabasecommon.h"
-#include "diagresultsdbsession.h"
-#include "diagresultsdbserver.h"
-#include "diagresultsdbtestrecordsubsession.h"
-#include "diagresultsdatabasetestrecordinfo.h"
-#include "diagresultsdbtestrecordhandle.h"
-#include "diagresultsdbtestrecord.h"
-#include "diagresultsdatabaseitem.h"
-#include "diagresultsdbrecordinfoarraypacked.h"
-#include "diagresultsdbcrdc.h"
-#include "diagresultsdbrecordengineparam.h"
-
-//System includes
-#include <s32mem.h>
-
-const TInt KArrayGranuality = 50;
-const TInt KResultsDatabaseBufferLength=0x700;
-
-// ---------------------------------------------------------------------------
-// constructor - must pass client to CSession
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDbSession::CDiagResultsDbSession(CDiagResultsDbServer * aServer):
- iServer(aServer), iSubsessionContainer( NULL ), iSubsessionIndex(NULL),
- iLastResultCommand( 0 ),
- iStore(NULL), iBufferedLastResults(NULL), iBufferedSingleResult(NULL),
- iHasWrittenData(EFalse)
- {
- aServer->IncreaseSessionCount();
- }
-
-// ---------------------------------------------------------------------------
-// NewL.
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDbSession* CDiagResultsDbSession::NewL(CDiagResultsDbServer * aServer)
- {
- CDiagResultsDbSession* pSession= new (ELeave) CDiagResultsDbSession( aServer );
- CleanupStack::PushL( pSession );
- pSession->ConstructL();
- CleanupStack::Pop();
- return pSession;
- }
-
-// ---------------------------------------------------------------------------
-// ConstructL.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::ConstructL()
- {
- iSubsessionContainer = iServer->NewContainerL();
- iSubsessionIndex = CObjectIx::NewL();
-
- // buffer for IPC. Objects are transmitted in this buffer.
- // Size of the buffer has to be selected carefully.
- // It should be 'large enough' but not too large.
- // If you see too many overflows, increase the size.
- iBuffer = CBufFlat::NewL(KArrayGranuality);
- iBuffer->ResizeL(KResultsDatabaseBufferLength);
- }
-
-// ---------------------------------------------------------------------------
-// Destructor.
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDbSession::~CDiagResultsDbSession()
- {
- if ( iBuffer )
- {
- iBuffer->Reset();
- delete iBuffer;
- iBuffer = NULL;
- }
-
- // NOTE!
- // The deletion order is important here. You must
- // delete object indexes first, because this zeros the
- // number of references to any CObject type objects. Trying
- // to delete object container first, you get panic
- // E32USER-CBase 33: an attempt is made to delete the CObject
- // when the reference count is not zero.
- delete iSubsessionIndex;
-
- if ( iSubsessionContainer )
- {
- iServer->RemoveContainer( iSubsessionContainer );
- }
-
- delete iStore;
-
- if ( iServer )
- {
- iServer->DecreaseSessionCount();
- }
-
- if ( iBufferedLastResults )
- {
- iBufferedLastResults->ResetAndDestroy();
- iBufferedLastResults->Close();
- delete iBufferedLastResults;
- iBufferedLastResults = 0;
- }
-
- if ( iBufferedSingleResult )
- {
- delete iBufferedSingleResult;
- iBufferedSingleResult = NULL;
- }
- }
-
-// ---------------------------------------------------------------------------
-// Service client requests.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::ServiceL(const RMessage2& aMessage)
- {
- LOGME("CDiagResultsDbSession::ServiceL");
- TBool async = EFalse;
- TRAPD( err, async = DispatchMessageL( aMessage ) );
- LOGME1("CDiagResultsDbSession::ServiceL %d",err);
- if ( !async )
- {
- aMessage.Complete( err );
- }
- }
-
-// ---------------------------------------------------------------------------
-// service a client request; test the opcode and then do appropriate servicing
-// ---------------------------------------------------------------------------
-//
-TBool CDiagResultsDbSession::DispatchMessageL(const RMessage2 &aMessage)
- {
- LOGME("CDiagResultsDbSession::DispatchMessageL");
- iMsg = aMessage;
- TInt function = aMessage.Function();
- LOGME1("CDiagResultsDbSession::DispatchMessageL - %d",function);
- TInt handle(0);
- CObject* subsession = NULL;
- switch( function )
- {
- case DiagResultsDbCommon::EConnect:
- {
- LOGME("CDiagResultsDbSession::EConnect");
- TPckgBuf<TUid> uidpckg;
- aMessage.Read(0, uidpckg);
- iDbUid = uidpckg();
-
- iStore = CDiagResultsDbStore::NewL( iDbUid );
- return EFalse;
- }
-
- case DiagResultsDbCommon::EClose:
- {
- LOGME("CDiagResultsDbSession::EClose");
- aMessage.Complete (KErrNone);
-
- return ETrue;
- }
-
- case DiagResultsDbCommon::EGetRecordCount:
- {
- LOGME("CDiagResultsDbSession::EGetRecordCount");
- RArray<TUid> uids;
- CleanupClosePushL ( uids );
- iStore->RecordUidsL( uids );
-
- TPckgBuf<TUint> pckg( uids.Count() );
- aMessage.Write(0, pckg);
-
- CleanupStack::PopAndDestroy( &uids );
- return EFalse;
- }
-
- case DiagResultsDbCommon::EConnectSubsession:
- LOGME("CDiagResultsDbSession::EConnectSubsession");
- ConnectSubsessionL( aMessage );
- return EFalse;
-
- case DiagResultsDbCommon::ESubsessionCreateNewRecord:
- LOGME("CDiagResultsDbSession::ESubsessionCreateNewRecord");
- CreateNewRecordL( aMessage );
- HasWritten();
- return EFalse;
-
- case DiagResultsDbCommon::ECloseSubsession:
- LOGME("CDiagResultsDbSession::ECloseSubsession");
- CloseSubsessionL();
- return EFalse;
-
- case DiagResultsDbCommon::EGetLastRecord:
- LOGME("CDiagResultsDbSession::EGetLastRecord");
- GetLastRecordL( aMessage );
- return EFalse;
-
- case DiagResultsDbCommon::EGetLastNotCompletedRecord:
- LOGME("CDiagResultsDbSession::EGetLastNotCompletedRecord");
- GetLastNotCompletedRecordL( aMessage );
- return EFalse;
-
- case DiagResultsDbCommon::EGetRecordList: //record uids
- LOGME("CDiagResultsDbSession::EGetRecordList");
- GetRecordListL( aMessage );
- return EFalse;
-
- case DiagResultsDbCommon::EGetRecordInfoList:
- LOGME("CDiagResultsDbSession::EGetRecordInfoList");
- GetRecordInfoListL( aMessage );
- return EFalse;
-
- case DiagResultsDbCommon::EInitiateGetLastResults: //Async
- {
- LOGME("CDiagResultsDbSession::EInitiateGetLastResults");
- ReadBufferL( aMessage, 0, iBuffer );
-
- iLastResultsMsg = iMsg;
-
- iLastResultCommand = DiagResultsDbCommon::EInitiateGetLastResults;
-
- if ( iBufferedLastResults )
- {
- iBufferedLastResults->ResetAndDestroy();
- iBufferedLastResults->Close();
- delete iBufferedLastResults;
- iBufferedLastResults = 0;
- }
-
- iStore->ExistingRecordsAsyncL( *this );
- return ETrue;
- }
-
- case DiagResultsDbCommon::EInitiateGetSingleLastResult: //Async
- {
- LOGME("CDiagResultsDbSession::EInitiateGetSingleLastResult");
- iLastSingleResultsMsg = iMsg;
-
- iLastResultCommand = DiagResultsDbCommon::EInitiateGetSingleLastResult;
-
- if ( iBufferedSingleResult )
- {
- delete iBufferedSingleResult;
- iBufferedSingleResult = NULL;
- }
-
- iStore->ExistingRecordsAsyncL( *this );
- return ETrue;
- }
-
-
- case DiagResultsDbCommon::EGetLastResults:
- LOGME("CDiagResultsDbSession::EGetLastResults");
- GetLastResultsL( aMessage );
- return EFalse;
-
- case DiagResultsDbCommon::EGetSingleLastResult:
- LOGME("CDiagResultsDbSession::EGetSingleLastResult");
- GetSingleLastResultL( aMessage );
- return EFalse;
-
- case DiagResultsDbCommon::ECancelInitiateGetLastResults:
- {
- LOGME("CDiagResultsDbSession::ECancelInitiateGetLastResults");
- CancelLastResultsL( aMessage );
- return EFalse;
- }
-
- // Sub-session requests. See CDiagResultsDbTestRecordSubsession.
- case DiagResultsDbCommon::ESubsessionGetTestRecordId:
- case DiagResultsDbCommon::ESubsessionTestCompleted:
- case DiagResultsDbCommon::ESubsessionIsTestCompleted:
- case DiagResultsDbCommon::ESubsessionGetRecordInfo:
- case DiagResultsDbCommon::ESubsessionGetTestUids:
- case DiagResultsDbCommon::ESubsessionSuspend:
- case DiagResultsDbCommon::ESubsessionIsSuspended:
- case DiagResultsDbCommon::ESubsessionLogTestResult:
- case DiagResultsDbCommon::ESubsessionGetTestResult:
- case DiagResultsDbCommon::ESubsessionGetTestResults:
- case DiagResultsDbCommon::ESubsessionGetEngineParam:
- case DiagResultsDbCommon::ESubsessionGetStatus:
- case DiagResultsDbCommon::ESubsessionCancelLogTestResult:
- LOGME("CDiagResultsDbSession::ESubsessionCancelLogTestResult");
- handle = aMessage.Int3();
- subsession = iSubsessionIndex->At( handle );
- return static_cast<CDiagResultsDbTestRecordSubsession*>(subsession)
- ->DispatchMessageL( aMessage );
- default:
- aMessage.Panic( _L("DiagSrv panic: unknown command"),
- DiagResultsDbCommon::EBadRequest );
- return EFalse;
- }
- }
-
-// ---------------------------------------------------------------------------
-// Get function.
-// ---------------------------------------------------------------------------
-//
-TBool CDiagResultsDbSession::SessionHasWritten() const
- {
- return iHasWrittenData;
- }
-
-// ---------------------------------------------------------------------------
-// Connect to a subsession. Test record represents the connected subsession.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::ConnectSubsessionL( const RMessage2 &aMessage )
- {
- TPckgBuf<TUid> uidpckg;
- aMessage.Read(0, uidpckg);
- TUid recordUid = uidpckg();
-
- TPckgBuf<TBool> readOnlyPckg;
- aMessage.Read(1, readOnlyPckg);
- TBool readonly = readOnlyPckg();
-
- CDiagResultsDbTestRecordHandle* handle = iStore->OpenExistingHandleL(
- recordUid );
-
- if ( readonly )
- {
- // keep the record as it is.
- }
- else
- {
- if ( handle->RecordInfo().iCompleted )
- {
- delete handle;
- handle = 0;
- User::Leave( KErrAlreadyExists );
- }
-
- handle->RecordInfo().iRecordStatus =
- TDiagResultsDatabaseTestRecordInfo::EOpen;
- }
-
- CreateSubsessionL( handle, readonly );
- }
-
-// ---------------------------------------------------------------------------
-// Create a new record. This does not write data into the db file.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::CreateNewRecordL ( const RMessage2 &aMessage )
- {
-
- ReadBufferL( aMessage, 1, iBuffer );
-
- RBufReadStream stream( *iBuffer );
- CleanupClosePushL ( stream );
-
- CDiagResultsDbRecordEngineParam* params =
- CDiagResultsDbRecordEngineParam::NewL ( stream );
- CleanupStack::PushL( params );
-
- CDiagResultsDbTestRecordHandle* handle = iStore->CreateNewRecordL( params );
-
- handle->RecordInfo().iRecordStatus =
- TDiagResultsDatabaseTestRecordInfo::EOpen;
-
- CleanupStack::Pop(); //params
- CleanupStack::PopAndDestroy( &stream );
-
- CreateSubsessionL(handle, EFalse);
-
- TPckgBuf<TUid> recorduidpckg( handle->RecordInfo().iRecordId );
-
- aMessage.Write(0, recorduidpckg );
- }
-
-// ---------------------------------------------------------------------------
-// Return the database file uid.
-// ---------------------------------------------------------------------------
-//
-TUid CDiagResultsDbSession::DbUid() const
- {
- return iDbUid;
- }
-
-// ---------------------------------------------------------------------------
-// Create a new subsession.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::CreateSubsessionL(
- CDiagResultsDbTestRecordHandle* aTestRecordHandle,
- TBool aReadonly )
- {
- TInt handle(0);
- CObject* subsession = NULL;
-
- // Create sub-session object
- subsession = CDiagResultsDbTestRecordSubsession::NewL( this,
- aTestRecordHandle,
- aReadonly );
- CleanupStack::PushL( subsession );
- iSubsessionContainer->AddL( subsession );
- CleanupStack::Pop();
-
- // Create sub-session handle
- TRAPD( err, handle = iSubsessionIndex->AddL( subsession ) );
-
- // Remember to remove session object from object container
- if( err != KErrNone )
- {
- iSubsessionContainer->Remove( subsession );
- User::Leave( DiagResultsDbCommon::ESvrCreateSubsession );
- }
-
- // Package to pass information to the client
- TPckgC<TInt> handlePckg(handle);
-
- // Send handle to the client
- TRAP( err, iMsg.WriteL( 3, handlePckg ) );
- if( err != KErrNone )
- {
- iSubsessionIndex->Remove(handle);
- User::Leave( DiagResultsDbCommon::ESvrCreateSubsession );
- }
-
- return;
- }
-
-// ---------------------------------------------------------------------------
-// Close existing subsession.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::CloseSubsessionL()
- {
- TInt handle = iMsg.Int3();
- iSubsessionIndex->Remove(handle);
- }
-
-// ---------------------------------------------------------------------------
-// Return store that is responsible for handling the database file.
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDbStore& CDiagResultsDbSession::Store()
- {
- return *iStore;
- }
-
-// ---------------------------------------------------------------------------
-// Service function. Searches for newest test results.
-// Related functions:
-// ExistingRecordsAsyncL (initiates async fetch of test records)
-// CancelLastResultsL (cancel async fetch)
-// ExistingRecordsL (retrieves test records)
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::GetLastResultsL( const RMessage2 &aMessage )
- {
- if ( iBufferedLastResults == NULL )
- {
- User::Leave ( KErrNotFound );
- }
-
- ReadBufferL( aMessage, 0, iBuffer );
-
- RBufWriteStream stream ( *iBuffer );
- CleanupClosePushL( stream );
-
- stream.WriteInt16L( iBufferedLastResults->Count() );
-
- for ( TInt i = 0; i < iBufferedLastResults->Count(); ++i )
- {
- CDiagResultsDatabaseItem* item = (*iBufferedLastResults)[i];
-
- if ( item == NULL )
- {
- stream.WriteUint8L(0);
- }
- else
- {
- stream.WriteUint8L(1);
- (*iBufferedLastResults)[i]->ExternalizeL( stream );
- }
- }
-
- if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) )
- {
- User::Leave( KErrOverflow );
- }
-
- stream.CommitL();
-
- CleanupStack::PopAndDestroy( &stream );
-
- aMessage.Write( 0, iBuffer->Ptr(0) ); //write to client's address space
-
- iBufferedLastResults->ResetAndDestroy();
- iBufferedLastResults->Close();
- delete iBufferedLastResults;
- iBufferedLastResults = NULL;
- }
-
-
-// ---------------------------------------------------------------------------
-// Service function. Get single test result (the newest).
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::GetSingleLastResultL( const RMessage2 &aMessage )
- {
- ReadBufferL( aMessage, 0, iBuffer );
-
- RBufWriteStream stream ( *iBuffer );
- CleanupClosePushL( stream );
-
- if ( iBufferedSingleResult )
- {
- stream.WriteInt8L( 1 );
-
- iBufferedSingleResult->ExternalizeL( stream );
-
- }
- else //NULL
- {
- stream.WriteInt8L( 0 );
- }
-
- stream.CommitL();
- CleanupStack::PopAndDestroy( &stream );
-
- aMessage.Write( 0, iBuffer->Ptr(0) );
-
- delete iBufferedSingleResult;
- iBufferedSingleResult = NULL;
- }
-
-
-// ---------------------------------------------------------------------------
-// Service function. Cancel InitiateGetLastResults method.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::CancelLastResultsL( const RMessage2 & /*aMessage*/ )
- {
- if ( !iLastResultsMsg.IsNull() )
- {
- iStore->Cancel();
- iLastResultsMsg.Complete( KErrCancel );
-
- if ( iBufferedLastResults )
- {
- iBufferedLastResults->ResetAndDestroy();
- delete iBufferedLastResults;
- iBufferedLastResults = NULL;
- }
- }
- }
-
-// ---------------------------------------------------------------------------
-// Service function. Retrieve uid of the newest test record.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::GetLastRecordL( const RMessage2 &aMessage )
- {
- RArray<TUid> uids;
- CleanupClosePushL ( uids );
- iStore->RecordUidsL( uids );
-
- if ( uids.Count() == 0 )
- {
- User::Leave( KErrNotFound );
- }
-
- TPckgBuf<TUid> pckg( uids[uids.Count() -1] ); //newest record is the last
- aMessage.Write( 0, pckg );
-
- CleanupStack::PopAndDestroy( &uids );
- }
-
-
-// ---------------------------------------------------------------------------
-// Service function. Try to find a test record that was suspended.
-// Leave with KErrNotFound if such test record is not found.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::GetLastNotCompletedRecordL( const RMessage2 &aMessage )
- {
- RArray<TUid> uids;
- CleanupClosePushL ( uids );
- iStore->RecordUidsL( uids );
-
- TBool found = EFalse;
-
- // newest record are on the top.
- for (TInt i = uids.Count() -1; i >= 0; --i)
- {
- CDiagResultsDbTestRecordHandle* handle =
- iStore->OpenExistingHandleL( uids[i] );
-
- CleanupStack::PushL (handle);
-
- if( handle->RecordInfo().iRecordStatus !=
- TDiagResultsDatabaseTestRecordInfo::ECompleted &&
- !handle->RecordInfo().iCompleted )
-
- {
- TPckgBuf<TUid> pckg( handle->RecordInfo().iRecordId );
- aMessage.Write( 0, pckg );
- found = ETrue;
- CleanupStack::PopAndDestroy( handle );
- break;
- }
-
- CleanupStack::PopAndDestroy( handle );
- }
-
- CleanupStack::PopAndDestroy( &uids );
-
- if ( !found )
- {
- User::Leave ( KErrNotFound );
- }
- }
-
-// ---------------------------------------------------------------------------
-// Service function. Retrieve all test record uids that there are.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::GetRecordListL( const RMessage2 &aMessage )
- {
- ReadBufferL( aMessage, 0, iBuffer );
-
- RArray<TUid> uids;
- CleanupClosePushL( uids );
- iStore->RecordUidsL( uids );
-
- RBufWriteStream stream ( *iBuffer );
- CleanupClosePushL( stream );
- stream.WriteInt16L( uids.Count() );
-
- for ( TInt i = 0; i < uids.Count(); ++i )
- {
- stream.WriteInt32L( uids[i].iUid );
- }
-
- if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) )
- {
- User::Leave( KErrOverflow );
- }
-
- aMessage.Write( 0, iBuffer->Ptr(0) ); //write to client's address space
-
- CleanupStack::PopAndDestroy( &stream );
- CleanupStack::PopAndDestroy( &uids );
-
- }
-
-// ---------------------------------------------------------------------------
-// Service function. Return overviews of test records.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::GetRecordInfoListL( const RMessage2 &aMessage )
- {
- ReadBufferL( aMessage, 0, iBuffer );
-
- CArrayFixFlat<TDiagResultsDatabaseTestRecordInfo>* array = new (ELeave)
- CArrayFixFlat<TDiagResultsDatabaseTestRecordInfo>(KArrayGranuality);
- CleanupStack::PushL (array);
-
- RArray<TUid> uids;
- CleanupClosePushL ( uids );
- iStore->RecordUidsL( uids );
-
- for (TInt i = 0; i < uids.Count(); ++i)
- {
- CDiagResultsDbTestRecordHandle* handle =
- iStore->OpenExistingHandleL( uids[i] );
-
- CleanupStack::PushL (handle);
- array->AppendL( handle->RecordInfo() );
-
- CleanupStack::PopAndDestroy( handle );
- }
-
- CleanupStack::PopAndDestroy( &uids );
-
- TDiagResultsDbRecordInfoArrayPacked packedArray ( iBuffer );
- packedArray.PackArrayL ( *array );
-
- if ( iBuffer->Ptr(0).Length() > aMessage.GetDesMaxLength(0) )
- {
- User::Leave( KErrOverflow );
- }
-
- aMessage.Write( 0, iBuffer->Ptr(0) ); //write to client's address space
-
- CleanupStack::PopAndDestroy( array );
-
- }
-
-// ---------------------------------------------------------------------------
-// Helper function to read a buffer from client side. Leaves the buffer
-// onto cleanup stack IF it has to create a new one.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::ReadBufferL(const RMessage2& aMessage, TInt aParam,
- CBufFlat*& aBuffer)
- {
- TInt desLen = aMessage.GetDesLengthL(aParam);
-
- if(desLen >= 0)
- {
- if (aBuffer==NULL)
- {
- aBuffer = CBufFlat::NewL(KArrayGranuality);
- aBuffer->ResizeL(desLen);
- CleanupStack::PushL(aBuffer);
- }
- else if (desLen > aBuffer->Ptr(0).MaxLength())
- {
- iBuffer->Delete( 0, iBuffer->Size() ); // delete old data.
- // we have to increase the size of aBuffer
- aBuffer->ResizeL(desLen);
- }
-
- TPtr8 desPtr = aBuffer->Ptr(0);
- aMessage.ReadL(aParam, desPtr);
-
- }
- else
- {
- // desLen is negative leave with an error.
- User::Leave(KErrArgument);
- }
- }
-
-// ---------------------------------------------------------------------------
-// Store observer method. This is called after store has retrieved
-// test records from the DB file.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::ExistingRecordsL( TInt aError,
- RPointerArray<CDiagResultsDbTestRecord>* aArray )
- {
- CleanupStack::PushL ( aArray );
- CleanupResetAndDestroyClosePushL( *aArray );
-
- //Check if there were any errors during loading the test records.
- if ( aError != KErrNone )
- {
-
- if ( iLastResultCommand ==
- DiagResultsDbCommon::EInitiateGetLastResults )
- {
- iLastResultsMsg.Complete ( aError );
- }
- else if ( iLastResultCommand ==
- DiagResultsDbCommon::EInitiateGetSingleLastResult )
- {
- iLastSingleResultsMsg.Complete ( aError );
- }
-
- CleanupStack::PopAndDestroy( aArray );
- CleanupStack::PopAndDestroy( aArray ); //delete the pointer
- return;
- }
-
- switch( iLastResultCommand )
- {
-
- //Find multiple last results
- //buffer contains the uids to be searched.
- //See RDiagResultsDatabase::InitiateGetLastResults.
- case DiagResultsDbCommon::EInitiateGetLastResults:
- {
- //Trap is needed so that we can complete client's request
- //if any errors occur.
- TRAPD(error, FindLastResultsL( *aArray ));
-
- if ( error != KErrNone )
- {
- iLastResultsMsg.Complete (error);
- break;
- }
- else
- {
- iLastResultsMsg.Complete (KErrNone);
- }
-
- break;
- }
-
- // Find single test result
- // see RDiagResultsDatabase::InitiateGetLastResult.
- case DiagResultsDbCommon::EInitiateGetSingleLastResult:
- {
- TPckgBuf<TUid> uidpckg;
- iLastSingleResultsMsg.Read(0, uidpckg);
- TUid resultsItemUid = uidpckg();
-
- CDiagResultsDatabaseItem* item = NULL;
-
- // Trap any errors and complete client's request if there
- // are any errors.
- TRAPD(error, item = FindDatabaseItemL( resultsItemUid, aArray)) ;
-
- if ( error != KErrNone )
- {
- delete item;
- item = NULL;
-
- iLastSingleResultsMsg.Complete (error);
- break;
- }
-
- if ( item == NULL ) //Not found
- {
- iBufferedSingleResult = NULL;
-
- //Check also the last results buffer
- CheckLastResultsBufferL( resultsItemUid, iBufferedSingleResult );
- }
- else
- {
- iBufferedSingleResult = item;
- }
-
-
-
- iLastSingleResultsMsg.Complete (KErrNone);
- break;
- }
-
- default:
- {
- User::Panic ( _L("Diag results DB"),
- DiagResultsDbCommon::EUnknownLastResultState );
- }
- }
-
- iLastResultCommand = 0;
-
- CleanupStack::PopAndDestroy( aArray ); //call reset and destroy + close
- CleanupStack::PopAndDestroy( aArray ); //delete the pointer
- }
-
-
-// ---------------------------------------------------------------------------
-// Read UIDs from a stream and search last results.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::FindLastResultsL(
- RPointerArray<CDiagResultsDbTestRecord>& aArray )
- {
-
- CArrayFixFlat<TUid>* uidArray = new (ELeave)
- CArrayFixFlat<TUid>(KArrayGranuality);
- CleanupStack::PushL( uidArray );
-
- RBufReadStream stream( *iBuffer );
- CleanupClosePushL ( stream );
-
- TInt8 count = stream.ReadInt8L();
-
- for ( TInt i = 0; i < count; ++i )
- {
- TInt32 uid = stream.ReadInt32L();
-
- uidArray->AppendL( TUid::Uid( uid ));
- }
-
- CleanupStack::PopAndDestroy( &stream );
-
- iBufferedLastResults = new (ELeave) RPointerArray<CDiagResultsDatabaseItem>;
-
- SearchLastResultsL( *uidArray, aArray, *iBufferedLastResults );
-
- //last results could be also in the last results buffer.
- CheckLastResultsBufferL( *uidArray, *iBufferedLastResults );
-
- // there must be exactly the same number of cells in both arrays.
- if ( uidArray->Count() != iBufferedLastResults->Count() )
- {
- User::Panic ( _L("Diag results DB"),
- DiagResultsDbCommon::EGetLastResultsMismatch );
- }
-
- CleanupStack::PopAndDestroy( uidArray );
- }
-
-
-// ---------------------------------------------------------------------------
-// Check last result buffer for test results.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::CheckLastResultsBufferL(
- const CArrayFixFlat<TUid>& aUidArray,
- RPointerArray<CDiagResultsDatabaseItem>& aResultsArray )
- {
- CDiagResultsDbTestRecord* buffer = iStore->OpenExistingLastResultsBufferL();
- CleanupStack::PushL( buffer );
-
- for (TInt i = 0; i < aResultsArray.Count(); ++i)
- {
- if ( aResultsArray[i] == NULL )
- {
- TUid uid = aUidArray[i];
-
- CDiagResultsDatabaseItem* item = buffer->FindTestRecord( uid );
-
- if ( item )
- {
- buffer->RemoveL( uid );
- aResultsArray[i] = item;
- }
- }
- }
-
- CleanupStack::PopAndDestroy( buffer );
- }
-
-
-// ---------------------------------------------------------------------------
-// Check last result buffer for test result.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::CheckLastResultsBufferL(
- TUid aTestUid,
- CDiagResultsDatabaseItem*& aResult )
- {
-
-
- CDiagResultsDbTestRecord* buffer = iStore->OpenExistingLastResultsBufferL();
- CleanupStack::PushL( buffer );
-
- CDiagResultsDatabaseItem* item = buffer->FindTestRecord( aTestUid );
-
- if ( item )
- {
- buffer->RemoveL( aTestUid );
- aResult = item;
- }
-
- CleanupStack::PopAndDestroy( buffer );
- }
-
-
-// ---------------------------------------------------------------------------
-// Searches for the newest test results.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::SearchLastResultsL(
- const CArrayFixFlat<TUid>& aUidArray,
- RPointerArray<CDiagResultsDbTestRecord>& aTestRecordArray,
- RPointerArray<CDiagResultsDatabaseItem>& aResultsArray )
-
- {
- //Search all records for certain uid.
- for ( TInt i = 0; i < aUidArray.Count(); ++i )
- {
-
- CDiagResultsDatabaseItem* item =
- FindDatabaseItemL( aUidArray[i], &aTestRecordArray );
-
- if ( item == NULL ) //Not found
- {
- aResultsArray.Append(NULL);
- }
- else
- {
- aResultsArray.Append( item );
- }
- }
- }
-
-
-// ---------------------------------------------------------------------------
-// Indicates has session written any data into the DB file.
-// To be exact only subsession writes data into the file.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::HasWritten()
- {
- iHasWrittenData = ETrue;
- }
-
-// ---------------------------------------------------------------------------
-// Turn off compacting.
-// ---------------------------------------------------------------------------
-//
-void CDiagResultsDbSession::DoNotCompact()
- {
- iHasWrittenData = EFalse;
- }
-
-// ---------------------------------------------------------------------------
-// Helper function to seach an item from a pointer array.
-// Starts from the newest record to search for an UID.
-// ---------------------------------------------------------------------------
-//
-CDiagResultsDatabaseItem* CDiagResultsDbSession::FindDatabaseItemL( TUid aUid,
- RPointerArray<CDiagResultsDbTestRecord>* aArray )
- {
-
- //Check that there is a test record.
- if ( !aArray || aArray->Count() == 0 )
- {
- return NULL;
- }
-
- // start from the newest record
- for (TInt x = aArray->Count() -1; x >= 0 ; --x )
- {
- CDiagResultsDbTestRecord* record = (*aArray)[x];
-
- //Assumes that there is only MAX one specific UID in the test record.
- for ( TInt y = 0; y < record->Count(); ++y )
- {
- CDiagResultsDatabaseItem* item = record->GetItem( y );
-
- // Search for a test result that is not skipped / cancelled.
- if ( item->TestUid() == aUid &&
- (item->TestResult() == CDiagResultsDatabaseItem::ESuccess ||
- item->TestResult() == CDiagResultsDatabaseItem::EFailed ))
- {
- //Remove the found item to speed up look up times.
- //This does not remove it from the DB file.
- record->RemoveL( y );
- return item;
- }
- }
- }
-
- return NULL;
- }