searcher/tsrc/logplayer/src/logplayermanager.cpp
author hgs
Fri, 15 Oct 2010 12:09:28 +0530
changeset 24 65456528cac2
parent 0 671dee74050a
permissions -rw-r--r--
201041

/*
* Copyright (c) 2010 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 Files
#include <e32cons.h>
#include <S32MEM.H>
#include <BACLINE.H>
#include "LogPlayerManager.h"
#include "CCPixIndexer.h"
#include "CCPixSearcher.h"
#include "CSearchDocument.h"

// Contants
const TUint KLogPlayerMaxIdLength = 20;
const TUint KLogPlayerMaxTimeStampLength = 20;
const TChar KDefineVolumeSeparator = '/';

_LIT8( KIndexer, "INDEXER" );
_LIT8( KSearcher, "SEARCHER" );

_LIT(KLogPlayerStart, "Starting Log Player\n");
_LIT(KLogPlayerStop, "Stopping Log Player\n");

void ExecuteLogL( const THandleInformation& aInformation )
    {
    CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
    CleanupStack::PushL(scheduler);
    CActiveScheduler::Install(scheduler);

    CLogPlayerManager* manager = CLogPlayerManager::NewLC(aInformation.iLogFileName);

    manager->ExecuteLogL( 0,
            aInformation.iFilePosition,
            aInformation.iHandleId,
            aInformation.iStartTime );

    CleanupStack::PopAndDestroy( manager );

    CleanupStack::PopAndDestroy(scheduler);
    }

TInt ThreadFunction(TAny* aParam)
    {
    CTrapCleanup* cleanup = CTrapCleanup::New();

    THandleInformation handleInformation = *(reinterpret_cast<THandleInformation*>( aParam ) );

    TRAPD( err, ExecuteLogL( handleInformation ) );

    delete cleanup;
    return err;
}

// ========================= MEMBER FUNCTIONS ==================================

// -----------------------------------------------------------------------------
// CLogPlayerManager::NewL()
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CLogPlayerManager* CLogPlayerManager::NewL( const TDesC& aLogFileName )
    {
    CLogPlayerManager* logPlayerManager = CLogPlayerManager::NewLC( aLogFileName );
    CleanupStack::Pop(logPlayerManager);
    return logPlayerManager;
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::NewLC()
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CLogPlayerManager* CLogPlayerManager::NewLC( const TDesC& aLogFileName )
    {
    CLogPlayerManager* logPlayerManager = new (ELeave) CLogPlayerManager( aLogFileName );
    CleanupStack::PushL(logPlayerManager);
    logPlayerManager->ConstructL();
    return logPlayerManager;
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::~CLogPlayerManager()
// Destructor.
// -----------------------------------------------------------------------------
//
CLogPlayerManager::~CLogPlayerManager()
    {
	// TODO: Clear iHandleInformationArray
	
    delete iLogPlayerTimer;
    
	delete iIndexer;
	delete iSearcher;
	iSession.Close();
	
	iReadStream.Close();
	iFile.Close();
	iFs.Close();
	
	delete iWait;
    }

void CLogPlayerManager::TimerCallback()
    {
	TRAP_IGNORE( ContinueExecutionL() );
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ExecuteLog()
// -----------------------------------------------------------------------------
//
void CLogPlayerManager::ExecuteLogL(
		CConsoleBase* aConsole,
		TInt aPosition,
		TInt aHandle,
		const TTime& aStartTime )
{
	iHandle = aHandle;
	iStartTime = aStartTime;
	
	if ( aConsole )
	{
        iConsole = aConsole;
		aConsole->Printf( KLogPlayerStart );
	}

	// Open read stream for file
    iReadStream.Attach( iFile, aPosition );
    
    if ( iHandle == -1 )
    {
    	iSession.StopHouseKeeping();
    }

    TRAP_IGNORE( ReadTimeAndWait() );

    iWait->Start();

    if ( iHandle == -1 )
    {
    	iSession.ContinueHouseKeeping();
    }

    if ( aConsole )
		{
    	aConsole->Printf( KLogPlayerStop );
		}
}

TInt CLogPlayerManager::ReadNumberL(RReadStream& aReadStream,
        TChar aSeparator)
    {
    TBuf8<KLogPlayerMaxIdLength> id;
    aReadStream.ReadL(id, aSeparator);
    TLex8 lexer(id);
    TInt idVal;
    lexer.Val(idVal);
    return idVal;
    }

void CLogPlayerManager::ReadTextL(RReadStream& aReadStream, TDes8& aText,
        TChar aSeparator)
    {
    aReadStream.ReadL(aText, aSeparator);
    aText.Trim();
    }

void CLogPlayerManager::ReadTextL(RReadStream& aReadStream, TDes8& aText,
        TInt aLength)
    {
    aReadStream.ReadL(aText, aLength);
    }

TInt64 CLogPlayerManager::ReadTimeStampL(RReadStream& aReadStream)
    {
    TBuf8<KLogPlayerMaxTimeStampLength> timeStamp;
    aReadStream.ReadL(timeStamp, KLogPlayerFieldSeparator);
    TLex8 lexer(timeStamp);
    TInt64 timeVal;
    TInt err = lexer.Val(timeVal);
    if (err != KErrNone)
        {
        User::Leave(KErrNotSupported);
        }
    return timeVal;
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ContinueExecutionL()
// -----------------------------------------------------------------------------
//
void CLogPlayerManager::ContinueExecutionL()
    {
    _LIT8( KOpenDb, "OPENDB" );
    _LIT8( KDefineVolume, "DEFINEVOLUME" );
    _LIT8( KReset, "RESET" );
    _LIT8( KFlush, "FLUSH" );
    _LIT8( KAdd, "ADD" );
    _LIT8( KUpdate, "UPDATE" );
    _LIT8( KDelete, "DELETE" );
    _LIT8( KSearch, "SEARCH" );
    _LIT8( KGet, "GET" );
    _LIT8( KCancel, "CANCEL" );
    _LIT8( KHouseKeep, "HOUSEKEEP" );


    // Note: Huge descriptor from stack. Re-use this if possible.
	// TODO: Remove and use member variable iTextBuffer
	TBuf8<KLogPlayerMaxTextLength> textBuffer;

	// Read command
	ReadTextL(iReadStream, textBuffer);

	// Command: OPENDB
	if (textBuffer.Compare(KOpenDb) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("OPENDB\n"));
            }
		TInt index = 0;
		TBool isSearcher = EFalse;
		HBufC* baseAppClass = ReadOpenDbL(iReadStream, index, isSearcher);
		CleanupStack::PushL( baseAppClass );

		if ( index == iHandle )
		{
			if ( isSearcher )
			{
				TRAP_IGNORE( iSearcher->OpenDatabaseL(*baseAppClass) );
			}
			else
			{
				TRAP_IGNORE( iIndexer->OpenDatabaseL(*baseAppClass) );
			}
		}
		CleanupStack::PopAndDestroy( baseAppClass );

		// Check if handler for this index is created
		if ( iHandle == -1 && !IsHandlerCreated( index ) )
		{
			THandleInformation handleInformation;
			handleInformation.iLogFileName = iLogFileName;
			handleInformation.iFilePosition = iStartPosition.Offset();
			handleInformation.iHandleId = index;
			handleInformation.iStartTime = iStartTime;

			iHandleInformationArray.Append( handleInformation );

			// Create new thread for this new handler
			// Thread name: "LogManager_" + handle id
			TBuf<KMaxFileName> threadName;
			_LIT( KThreadNameBase, "LogManager_" );
			threadName.Append( KThreadNameBase );
			threadName.AppendNum( index );

			// Create thread
			RThread thread;
			thread.Create( threadName,
					ThreadFunction,
					1024*10,
					0,
					&iHandleInformationArray[iHandleInformationArray.Count()-1] );
			thread.Resume();
		}
	}
	// Command: DEFINEVOLUME
	else if (textBuffer.Compare(KDefineVolume) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("DEFINEVOLUME\n"));
            }

		// Get QualifiedBaseAppClass
		ReadTextL(iReadStream, textBuffer, KDefineVolumeSeparator);
		HBufC* qualifiedBaseAppClass = HBufC::NewLC(textBuffer.Length());
		TUint textBufferLen = textBuffer.Length() - 1; // Remove separator at end
		qualifiedBaseAppClass->Des().Copy( textBuffer.Left( textBufferLen ) );
		qualifiedBaseAppClass->Des().Trim();

		// Get Index path
		ReadTextL(iReadStream, textBuffer, KLogPlayerFieldSeparatorEndLine);
		HBufC* indexDbPath = HBufC::NewLC(textBuffer.Length());
		indexDbPath->Des().Copy(textBuffer);

		if ( iHandle == -1 )
		{
			iSession.DefineVolume(*qualifiedBaseAppClass, *indexDbPath);
		}

		CleanupStack::PopAndDestroy(indexDbPath);
		CleanupStack::PopAndDestroy(qualifiedBaseAppClass);
	}
	// Command: RESET
	else if (textBuffer.Compare(KReset) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("RESET\n"));
            }

		TInt index = 0;
		ReadResetL(iReadStream, index);
		if ( index == iHandle )
		{
			TRAP_IGNORE( iIndexer->ResetL() );
		}
	}
	// Command: FLUSH
	else if (textBuffer.Compare(KFlush) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("FLUSH\n"));
            }

		TInt index = 0;
		ReadFlushL(iReadStream, index);
		if ( index == iHandle )
		{
			TRAP_IGNORE( iIndexer->FlushL() );
		}
	}
	// Command: ADD
	else if (textBuffer.Compare(KAdd) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("ADD\n"));
            }

		TInt index = 0;
		CSearchDocument* doc = ReadAddL(iReadStream, index);
		CleanupStack::PushL(doc);

		if ( index == iHandle )
		{
			TRAP_IGNORE( iIndexer->AddL(*doc) );
		}

		CleanupStack::PopAndDestroy(doc);
	}
	// Command: UPDATE
	else if (textBuffer.Compare(KUpdate) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("UPDATE\n"));
            }

		TInt index = 0;
		CSearchDocument* doc = ReadAddL(iReadStream, index);
		CleanupStack::PushL(doc);

		if ( index == iHandle )
		{
			TRAP_IGNORE( iIndexer->UpdateL(*doc) );
		}

		CleanupStack::PopAndDestroy(doc);
	}
	// Command: DELETE
	else if (textBuffer.Compare(KDelete) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("DELETE\n"));
            }

		TInt index = 0;
		HBufC* docUid = ReadDeleteL(iReadStream, index);
		CleanupStack::PushL(docUid);

		if ( index == iHandle )
		{
			TRAP_IGNORE( iIndexer->DeleteL(*docUid) );
		}

		CleanupStack::PopAndDestroy(docUid);
	}
	// Command: SEARCH
	else if (textBuffer.Compare(KSearch) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("SEARCH\n"));
            }

		TInt index = 0;
		HBufC* searchQuery = ReadSearchL(iReadStream, index);
		CleanupStack::PushL(searchQuery);

		if ( index == iHandle )
		{
			TRAP_IGNORE( iSearcher->SearchL(*this, *searchQuery) );
		}

		CleanupStack::PopAndDestroy(searchQuery);
	}
	// Command: GET
	else if (textBuffer.Compare(KGet) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("GET\n"));
            }

		TInt index = 0;
		TInt docIndex = ReadGetL(iReadStream, index);

		if ( index == iHandle )
		{
			TRAP_IGNORE( iSearcher->GetDocumentL(docIndex, *this) );
		}
	}
	// Command: CANCEL
	else if (textBuffer.Compare(KCancel) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("CANCEL\n"));
            }

		TInt index = 0;
		ReadCancelL(iReadStream, index);

		if ( index == iHandle )
		{
			iSearcher->Cancel();
		}
	}
	// Command: HOUSEKEEP
	else if (textBuffer.Compare(KHouseKeep) == 0)
	{
        if ( iConsole )
            {
            iConsole->Printf(_L("HOUSEKEEP\n"));
            }

		ReadHouseKeepingL(iReadStream);
		if ( iHandle == -1 )
		{
			iSession.ForceHouseKeeping();
		}
	}
	else
	{
		iWait->AsyncStop();
		return;
	}
	
	ReadTimeAndWait();
}

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadFlushL
// -----------------------------------------------------------------------------
//
void CLogPlayerManager::ReadFlushL(RFileReadStream& aReadStream, TInt& aIndex)
    {
    aIndex = ReadNumberL(aReadStream, KLogPlayerFieldSeparatorEndLine);
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadAddL
// -----------------------------------------------------------------------------
//
CSearchDocument* CLogPlayerManager::ReadAddL(RFileReadStream& aReadStream, TInt& aIndex)
    {
    aIndex = ReadNumberL(aReadStream);

    // Data is in serialized binary format preceded by size in bytes
    TInt serializedSize = ReadNumberL(aReadStream);
    HBufC8* data = HBufC8::NewLC(serializedSize);
    TPtr8 dataPtr = data->Des();
    ReadTextL(aReadStream, dataPtr, serializedSize);

    RDesReadStream desReadStream(*data);
    CleanupClosePushL(desReadStream);
    CSearchDocument* searchDocument = CSearchDocument::NewLC(
            desReadStream);

    CleanupStack::Pop(searchDocument);
    CleanupStack::PopAndDestroy(&desReadStream);
    CleanupStack::PopAndDestroy(data);

    // Remove new line
    ReadTextL(aReadStream, iTextBuffer, KLogPlayerFieldSeparatorEndLine);
    
    return searchDocument;
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadDeleteL
// -----------------------------------------------------------------------------
//
HBufC* CLogPlayerManager::ReadDeleteL(RFileReadStream& aReadStream, TInt& aIndex)
    {
    aIndex = ReadNumberL(aReadStream);

    ReadTextL(aReadStream, iTextBuffer, KLogPlayerFieldSeparatorEndLine);
    TBuf<KLogPlayerMaxTextLength> docUid16;
    docUid16.Copy(iTextBuffer);
    return docUid16.AllocL();
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadSearchL
// -----------------------------------------------------------------------------
//
HBufC* CLogPlayerManager::ReadSearchL(RFileReadStream& aReadStream, TInt& aIndex)
    {
    aIndex = ReadNumberL(aReadStream);

    ReadTextL(aReadStream, iTextBuffer, KLogPlayerFieldSeparatorEndLine);
    TBuf<KLogPlayerMaxTextLength> searchQuery;
    searchQuery.Copy(iTextBuffer);
    return searchQuery.AllocL();
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadGetL
// -----------------------------------------------------------------------------
//
TInt CLogPlayerManager::ReadGetL(RFileReadStream& aReadStream, TInt& aIndex)
    {
	aIndex = ReadNumberL(aReadStream);

	TInt docIndex = ReadNumberL(aReadStream,
            KLogPlayerFieldSeparatorEndLine);

	return docIndex;
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadCancelL
// -----------------------------------------------------------------------------
//
void CLogPlayerManager::ReadCancelL(RFileReadStream& aReadStream, TInt& aIndex)
    {
	aIndex = ReadNumberL(aReadStream,
            KLogPlayerFieldSeparatorEndLine);
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadHouseKeepingL
// -----------------------------------------------------------------------------
//
void CLogPlayerManager::ReadHouseKeepingL(RFileReadStream& aReadStream)
    {
    // Remove new line
    ReadTextL(aReadStream, iTextBuffer, KLogPlayerFieldSeparatorEndLine);
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadOpenDbL
// -----------------------------------------------------------------------------
//
HBufC* CLogPlayerManager::ReadOpenDbL(RFileReadStream& aReadStream, TInt& aIndex, TBool& aIsSearcher)
    {
    aIndex = ReadNumberL(aReadStream);

    // Read SEARCHER / INDEXER
    ReadTextL(aReadStream, iTextBuffer);
    if (iTextBuffer.Compare(KIndexer) == 0)
        {
        aIsSearcher = EFalse;
        }
    else if (iTextBuffer.Compare(KSearcher) == 0)
        {
        aIsSearcher = ETrue;
        }
    else // Unknown type
        {
        User::Leave(KErrNotSupported);
        }

    // Read base app class
    ReadTextL(aReadStream, iTextBuffer, KLogPlayerFieldSeparatorEndLine);
    TBuf<KLogPlayerMaxTextLength> baseAppClass16;
    baseAppClass16.Copy(iTextBuffer);
    return baseAppClass16.AllocL();
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadResetL
// -----------------------------------------------------------------------------
//
void CLogPlayerManager::ReadResetL(RFileReadStream& aReadStream, TInt& aIndex)
    {
    aIndex = ReadNumberL(aReadStream,
               KLogPlayerFieldSeparatorEndLine);
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::IsHandlerCreated
// -----------------------------------------------------------------------------
//
TBool CLogPlayerManager::IsHandlerCreated(TInt aIndex)
    {
	TBool ret = EFalse;
	
	for ( TInt i=0; i < iHandleInformationArray.Count(); i++ )
	{
		if ( iHandleInformationArray[i].iHandleId == aIndex )
		{
			ret = ETrue;
			break;
		}
	}
    
	return ret;
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ReadTimeAndWait
// -----------------------------------------------------------------------------
//
void CLogPlayerManager::ReadTimeAndWait()
    {
    // If command in current line is OPENDB with new handle id then new thread must
    // start execution at the start of current line. This is used in ContinueExecutionL
    TRAP_IGNORE( iStartPosition = iReadStream.Source()->TellL(MStreamBuf::ERead) );
    
    TInt64 timeStamp = 0;

    TRAPD( err, timeStamp = ReadTimeStampL(iReadStream) );
    if (err != KErrNone)
        {
        // EOF
        iWait->AsyncStop();
        return;
        }

    // First run of master thread
    if ( iStartTime.Int64() == 0 )
        {
        iStartTime.HomeTime();
        }

    iLogPlayerTimer->StartTimer( iStartTime + TTimeIntervalMicroSeconds(timeStamp) );
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::CLogPlayerManager()
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CLogPlayerManager::CLogPlayerManager( const TDesC& aLogFileName )
	: iStartTime(0), iLogFileName(aLogFileName)
    {
    }

// -----------------------------------------------------------------------------
// CLogPlayerManager::ConstructL()
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CLogPlayerManager::ConstructL()
    {
    iWait = new(ELeave) CActiveSchedulerWait();

	// Open session to Search Server
	User::LeaveIfError(iSession.Connect());
    
	// Open indexer and searcher
    iIndexer = CCPixIndexer::NewL(iSession);
    iSearcher = CCPixSearcher::NewL(iSession);

    // Open file for reading Log Player data
    User::LeaveIfError( iFs.Connect() );

    TInt err = iFile.Open( iFs, iLogFileName, EFileStream | EFileRead | EFileShareReadersOnly );
    User::LeaveIfError( err );
 
	iLogPlayerTimer = CLogPlayerTimer::NewL(this);
    }