diff -r 13d7c31c74e0 -r b183ec05bd8c devicediagnosticsfw/diagresultsdb/server/src/diagresultsdbsession.cpp --- a/devicediagnosticsfw/diagresultsdb/server/src/diagresultsdbsession.cpp Thu Aug 19 10:44: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 - -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 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 uids; - CleanupClosePushL ( uids ); - iStore->RecordUidsL( uids ); - - TPckgBuf 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(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 uidpckg; - aMessage.Read(0, uidpckg); - TUid recordUid = uidpckg(); - - TPckgBuf 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 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 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 uids; - CleanupClosePushL ( uids ); - iStore->RecordUidsL( uids ); - - if ( uids.Count() == 0 ) - { - User::Leave( KErrNotFound ); - } - - TPckgBuf 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 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 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 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* array = new (ELeave) - CArrayFixFlat(KArrayGranuality); - CleanupStack::PushL (array); - - RArray 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* 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 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& aArray ) - { - - CArrayFixFlat* uidArray = new (ELeave) - CArrayFixFlat(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; - - 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& aUidArray, - RPointerArray& 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& aUidArray, - RPointerArray& aTestRecordArray, - RPointerArray& 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* 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; - }