searcher/searchclient/src/rsearchserversession.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 02 Sep 2010 21:37:32 +0300
changeset 18 3e1f76dd2722
parent 15 cf5c74390b98
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* 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 <e32math.h>
#include <e32debug.h>
#include <S32MEM.H>
#include "common.h"
#include "SearchServerLogger.h"
#include "SearchServerCommon.h"
#include "RSearchServerSession.h"
#include "CSearchDocument.h"
#include "OstTraceDefinitions.h"
#ifdef OST_TRACE_COMPILER_IN_USE
#include "rsearchserversessionTraces.h"
#endif
#include "cpixwatchdogcommon.h"
#include <centralrepository.h>


// FUNCTION PROTOTYPES
static TInt StartServer( const TDesC& aServerName , TUid aServerUid );
static TInt CreateServerProcess( const TDesC& aServerName , TUid aServerUid );

// RsearchServerSession::RsearchServerSession()
// C++ default constructor can NOT contain any code, that might leave.
EXPORT_C RSearchServerSession::RSearchServerSession(): RSessionBase() 
	{
	// No implementation required
	}

// -----------------------------------------------------------------------------
// RsearchServerSession::Connect()
// Connects to the server and create a session.
// -----------------------------------------------------------------------------
EXPORT_C TInt RSearchServerSession::Connect()
	{
    //read the name and Uid of the search server
    TInt err = KErrNotReady;
    // get the watchdog repro 
    //TRAP_IGNORE is used to avoid the code scanner error
    CRepository* wdrepo = NULL;
    TRAP_IGNORE(wdrepo = CRepository::NewL( KWDrepoUidMenu ));
    if ( wdrepo )
        {
        HBufC* servername = NULL;
        TUid serveruid = {0};
        TBuf<KCenrepUidLength> temp;
        TInt64 value;
        TLex uidvalue;
        //read the searchserver UId
        if ( KErrNone == wdrepo->Get( KSearchServerUIDKey, temp ))
            {
            uidvalue.Assign(temp);
            if (KErrNone == uidvalue.Val( value,EHex ))
                serveruid.iUid = value;
            }
        //read the search server name
        if ( KErrNone == wdrepo->Get( KSearchServerNAMEKey, temp ))
            {
            //TRAP_IGNORE is used to avoid the code scanner error
            TRAP_IGNORE(servername = HBufC::NewL( temp.Length() ));
            TPtr ssname = servername->Des(); 
            ssname.Copy( temp );
            }
        // make sure the server is started before creating connection
        if ( servername )
           err = StartServer( *servername , serveruid );
    
        if ( KErrNone == err )
            {
            err = CreateSession(*servername, Version(), KDefaultMessageSlots);
            }
        delete servername;
        }
    delete wdrepo;
	return err;
	}

// -----------------------------------------------------------------------------
// A request to close the session.
// It makes a call to the server, which deletes the object container and object index
// for this session, before calling Close() on the base class.
// -----------------------------------------------------------------------------
EXPORT_C void RSearchServerSession::Close()
{
	SendReceive(ESearchServerCloseSession);
	RHandleBase::Close();
}

// -----------------------------------------------------------------------------
// RsearchServerSession::Version()
// Gets the version number.
// -----------------------------------------------------------------------------
//
EXPORT_C TVersion RSearchServerSession::Version() const
	{
	return (TVersion(KSearchServerMajorVersionNumber, KSearchServerMinorVersionNumber,
			KSearchServerBuildVersionNumber) );
	}

// -----------------------------------------------------------------------------
// RsearchServerSession::DefineVolumeL()
// Drops a qualified BaseAppClass
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RSearchServerSession::DefineVolume(const TDesC& aQualifiedBaseAppClass,
												 const TDesC& aIndexDbPath)
	{
	TIpcArgs args(&aQualifiedBaseAppClass, &aIndexDbPath);
	return SendReceive(ESearchServerDatabaseDefine, args);
	}

// -----------------------------------------------------------------------------
// RsearchServerSession::UnDefineVolumeL()
// Drops a qualified BaseAppClass
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RSearchServerSession::UnDefineVolume(const TDesC& aQualifiedBaseAppClass)
	{
	TIpcArgs args(&aQualifiedBaseAppClass);
	return SendReceive(ESearchServerDatabaseUnDefine, args);
	}

// -----------------------------------------------------------------------------
// RsearchServerSession::StopHouseKeeping()
// Stop housekeeping
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RSearchServerSession::StopHouseKeeping()
    {
    TInt err =  SendReceive(ESearchServerStopHouseKeeping, TIpcArgs());
	return err;
    }

// -----------------------------------------------------------------------------
// RsearchServerSession::ContinueHouseKeeping()
// Continue housekeeping
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RSearchServerSession::ContinueHouseKeeping()
    {
    return SendReceive(ESearchServerContinueHouseKeeping, TIpcArgs());
	}

// -----------------------------------------------------------------------------
// RsearchServerSession::ForceHouseKeeping()
// Force housekeeping
// -----------------------------------------------------------------------------
//
EXPORT_C TInt RSearchServerSession::ForceHouseKeeping()
    {
    return SendReceive(ESearchServerForceHouseKeeping, TIpcArgs());
	}

//
//
// RSearchServerSubSession
//
//


RSearchServerSubSession::RSearchServerSubSession():
	iEstimatedResultsCountPckg(iEstimatedResultsCount), 
	iDocumentSizePckg(iDocumentSize)
	{
	}

TInt RSearchServerSubSession::Open(RSearchServerSession& aSession)
	{
	return CreateSubSession(aSession, ESearchServerCreateSubSession);
	}

void RSearchServerSubSession::Close()
	{
	if (iSizeList)
       {
       delete iSizeList;
       iSizeList = NULL;
       }
	RSubSessionBase::CloseSubSession(ESearchServerCloseSubSession);
	}

void RSearchServerSubSession::OpenDatabaseL(const TBool aOpenForSearch, const TDesC& aBaseAppClass, const TDesC& aDefaultSearchField)
	{
	TIpcArgs args(&aBaseAppClass, &aDefaultSearchField, aOpenForSearch);
	User::LeaveIfError( SendReceive(ESearchServerOpenDatabase, args) );
	}

void RSearchServerSubSession::OpenDatabase(const TBool aOpenForSearch, const TDesC& aBaseAppClass, const TDesC& aDefaultSearchField, TRequestStatus& aStatus)
	{
	TIpcArgs args(&aBaseAppClass, &aDefaultSearchField, aOpenForSearch);
	SendReceive(ESearchServerOpenDatabase, args, aStatus);
	}

EXPORT_C void RSearchServerSubSession::SetAnalyzerL(const TDesC& aAnalyzer)
	{
	// Message arguments for the server
	TIpcArgs args(&aAnalyzer);

	// This call completes immediately, however the server will not
	// complete the request until later, so don't pass any local
	// descriptors as they will be out of scope by the time the server
	// attempts to read or write
	User::LeaveIfError( SendReceive(ESearchServerSetAnalyzer, args) ); 
	}

EXPORT_C void RSearchServerSubSession::SetAnalyzer(const TDesC& aAnalyzer, TRequestStatus& aStatus)
	{
	// Message arguments for the server
	TIpcArgs args(&aAnalyzer);

	// This call completes immediately, however the server will not
	// complete the request until later, so don't pass any local
	// descriptors as they will be out of scope by the time the server
	// attempts to read or write
	SendReceive(ESearchServerSetAnalyzer, args, aStatus);
	}

EXPORT_C void RSearchServerSubSession::SetQueryParserL(TInt aQueryParser)
	{
	TIpcArgs args(aQueryParser);

	// This call completes immediately, however the server will not
	// complete the request until later, so don't pass any local
	// descriptors as they will be out of scope by the time the server
	// attempts to read or write
	User::LeaveIfError( SendReceive(ESearchServerSetQueryParser, args) );
	}

EXPORT_C void RSearchServerSubSession::SetQueryParser(TInt aQueryParser, TRequestStatus& aStatus)
	{
	TIpcArgs args(aQueryParser);
	
	SendReceive(ESearchServerSetQueryParser, args, aStatus);
	}


// RSearchServerSubSession::Search()
EXPORT_C void RSearchServerSubSession::SearchL(const TDesC& aSearchTerms)
	{
	OstTraceFunctionEntry0( RSEARCHSERVERSUBSESSION_SEARCHL_ENTRY );
	PERFORMANCE_LOG_START("RSearchServerSubSession::SearchL");
	
	iEstimatedResultsCount = 0;

	// Message arguments for the server
	TIpcArgs args(&aSearchTerms, &iEstimatedResultsCountPckg);

	// This call completes immediately, however the server will not
	// complete the request until later, so don't pass any local
	// descriptors as they will be out of scope by the time the server
	// attempts to read or write
	User::LeaveIfError( SendReceive(ESearchServerSearch, args) );
	OstTrace1( TRACE_NORMAL, RSEARCHSERVERSUBSESSION_SEARCHL, "RSearchServerSubSession::SearchL::sync;iEstimatedResultsCount=%d", iEstimatedResultsCount );
	OstTraceFunctionExit0( RSEARCHSERVERSUBSESSION_SEARCHL_EXIT );
	}

EXPORT_C void RSearchServerSubSession::Search(const TDesC& aSearchTerms, TRequestStatus& aStatus)
	{
	OstTraceFunctionEntry0( RSEARCHSERVERSUBSESSION_SEARCH_ENTRY );
	PERFORMANCE_LOG_START("RSearchServerSubSession::SearchL");
	
	iEstimatedResultsCount = 0;

	// Message arguments for the server
	TIpcArgs args(&aSearchTerms, &iEstimatedResultsCountPckg);

	// This call completes immediately, however the server will not
	// complete the request until later, so don't pass any local
	// descriptors as they will be out of scope by the time the server
	// attempts to read or write
	SendReceive(ESearchServerSearch, args, aStatus);
	OstTraceFunctionExit0( RSEARCHSERVERSUBSESSION_SEARCH_EXIT );
	}

// RSearchServerSubSession::GetEstimatedDocumentCount()
TInt RSearchServerSubSession::GetEstimatedDocumentCount()
	{
	return iEstimatedResultsCount;
	}

// RSearchServerSubSession::GetDocument()
EXPORT_C CSearchDocument* RSearchServerSubSession::GetDocumentL(TInt aIndex)
	{
	OstTraceFunctionEntry0( RSEARCHSERVERSUBSESSION_GETDOCUMENTL_ENTRY );
	PERFORMANCE_LOG_START("RSearchServerSubSession::GetDocumentL");
	
	iDocumentSize = 0;

	// Message arguments for the server
	TIpcArgs args(aIndex, &iDocumentSizePckg);

	User::LeaveIfError( SendReceive(ESearchServerGetDocument, args ) );	
	
	return GetDocumentObjectL(); 
	}

EXPORT_C void RSearchServerSubSession::GetDocument(TInt aIndex, TRequestStatus& aStatus)
	{
	OstTraceFunctionEntry0( RSEARCHSERVERSUBSESSION_GETDOCUMENT_ENTRY );
	PERFORMANCE_LOG_START("RSearchServerSubSession::GetDocument");

	iDocumentSize = 0;

	// Message arguments for the server
	TIpcArgs args(aIndex, &iDocumentSizePckg);

	SendReceive(ESearchServerGetDocument, args, aStatus );	
	OstTraceFunctionExit0( RSEARCHSERVERSUBSESSION_GETDOCUMENT_EXIT );
	}


EXPORT_C CSearchDocument* RSearchServerSubSession::GetDocumentObjectL()
	{
	OstTraceFunctionEntry0( RSEARCHSERVERSUBSESSION_GETDOCUMENTOBJECTL_ENTRY );
	PERFORMANCE_LOG_START("CCPixSearcher::GetDocumentObjectL");
	
	CSearchDocument* document = NULL;
	if (iDocumentSize>0)
		{
		HBufC8* buf = HBufC8::NewLC(iDocumentSize);
		TPtr8 ptr = buf->Des();
		User::LeaveIfError(SendReceive(ESearchServerGetDocumentObject, TIpcArgs(&ptr)));

		RDesReadStream stream;
		stream.Open(ptr);
		stream.PushL();
		document = CSearchDocument::NewLC(stream);
		CleanupStack::Pop(document);
		CleanupStack::PopAndDestroy(&stream);
		CleanupStack::PopAndDestroy(buf);
		}
	
	OstTraceFunctionExit0( RSEARCHSERVERSUBSESSION_GETDOCUMENTOBJECTL_EXIT );
	return document;
	}

	// RSearchServerSubSession::GetBatchDocumentL()
EXPORT_C CSearchDocument** RSearchServerSubSession::GetBatchDocumentL(TInt aIndex, TInt& aReturnDoc, TInt aCount)
	{
	PERFORMANCE_LOG_START("RSearchServerSubSession::GetBatchDocumentL");
	
	if (!aCount) return NULL;
	
	iDocumentSize = 0;
	iReqCount = aCount;
	
	if (iSizeList)
	    {
	    delete iSizeList;
	    iSizeList = NULL;
	    }
	iSizeList = STATIC_CAST(TInt *, User::AllocZL(iReqCount * sizeof(TInt)));
    TPtr8 blob((TUint8*)iSizeList, iReqCount * sizeof(TInt));
	// Message arguments for the server
	TIpcArgs args(aIndex, iReqCount, &blob);
	iDocSizeArray.Reset();
	User::LeaveIfError( SendReceive(ESearchServerGetBatchDocument, args ) );	
	
	return GetBatchDocumentObjectL( aReturnDoc ); 
	}
	
EXPORT_C void RSearchServerSubSession::GetBatchDocument(TInt aIndex, TRequestStatus& aStatus, TInt aCount)
	{
	PERFORMANCE_LOG_START("RSearchServerSubSession::GetBatchDocument");

	iDocumentSize = 0;
	iReqCount = aCount;
	    
    if (iSizeList)
        {
        delete iSizeList;
        iSizeList = NULL;
        }
    TRAP_IGNORE(iSizeList = STATIC_CAST(TInt *, User::AllocZL(iReqCount * sizeof(TInt))));
    //iDocSizeArray
    TPtr8 blob((TUint8*)iSizeList, iReqCount * sizeof(TInt));
	    
    // Message arguments for the server
    TIpcArgs args(aIndex, aCount, &blob);
    
	SendReceive(ESearchServerGetBatchDocument, args, aStatus );
	}
	
EXPORT_C CSearchDocument** RSearchServerSubSession::GetBatchDocumentObjectL( TInt& aRetCount )
	{
	PERFORMANCE_LOG_START("CCPixSearcher::GetBatchDocumentObjectL");
	CSearchDocument** document = NULL;
	TInt i ,totalsize = 0;
	for ( i = 0; i< iReqCount; i++ )
        {
        if( *(iSizeList+i) )
            {
            totalsize += *(iSizeList+i);
            }
        else break;
        }   
	aRetCount = i;
	
	if ( aRetCount> 0 && totalsize )
	    {	    
	    //document = (CSearchDocument**)malloc ( sizeof(CSearchDocument*) * (i-1));
	    document = STATIC_CAST(CSearchDocument**, User::AllocL( aRetCount * sizeof(CSearchDocument*)));
	    HBufC8* buf = HBufC8::NewLC(totalsize +2 );
        TPtr8 ptr = buf->Des();
        User::LeaveIfError(SendReceive(ESearchServerGetBatchDocumentObject, TIpcArgs(&ptr)));	    
	    TInt startpos = 0;
	    TInt endpos = 0;
	    for ( TInt arrCount= 0; arrCount < aRetCount ; arrCount++)
                {
                endpos = *(iSizeList + arrCount) -4;
                //endpos = startpos + iDocSizeArray[arrCount];
                TPtrC8 tempptr = ptr.Mid( startpos , endpos );
                startpos += endpos;	        
                RDesReadStream stream;
                stream.Open(tempptr);
                stream.PushL();
                document[arrCount] = CSearchDocument::NewL(stream);
                CleanupStack::PopAndDestroy(&stream);
                }
        CleanupStack::PopAndDestroy(buf);	    
	    }		
	return document;
	}
	
// RSearchServerSubSession::CancelSearch()
// Cancels outstanding search from server
EXPORT_C void RSearchServerSubSession::CancelAll() const
	{
	SendReceive(ESearchServerCancelAll, TIpcArgs());
	}

// Adds the serialized document to the index
EXPORT_C void RSearchServerSubSession::Add(const TDesC8& aSerializedDocument, TRequestStatus& aStatus)
	{
	TIpcArgs args(&aSerializedDocument);	
	SendReceive(ESearchServerAdd, args, aStatus);
	}

// Updates the serialized document in the index
EXPORT_C void RSearchServerSubSession::Update(const TDesC8& aSerializedDocument, TRequestStatus& aStatus)
	{
	TIpcArgs args(&aSerializedDocument);	
	SendReceive(ESearchServerUpdate, args, aStatus);
	}

// Deletes the document uid in the index
EXPORT_C void RSearchServerSubSession::Delete(const TDesC& aDocUid, TRequestStatus& aStatus)
	{
	TIpcArgs args(&aDocUid);	
	SendReceive(ESearchServerDelete, args, aStatus);
	}

// Resets all of the documents in the index
EXPORT_C void RSearchServerSubSession::Reset(TRequestStatus& aStatus)
	{
	SendReceive( ESearchServerReset, aStatus );
	}

// Adds the serialized document to the index
EXPORT_C void RSearchServerSubSession::AddL(const TDesC8& aSerializedDocument)
	{
	TIpcArgs args( &aSerializedDocument );
	User::LeaveIfError( SendReceive(ESearchServerAdd, args) );
	}

// Updates the serialized document in the index
EXPORT_C void RSearchServerSubSession::UpdateL(const TDesC8& aSerializedDocument)
	{
	TIpcArgs args(&aSerializedDocument);
	OstTrace0( TRACE_NORMAL, RSEARCHSERVERSUBSESSION_UPDATEL, "RSearchServerSubSession::UpdateL(): sending the request to server" );
	CPIXLOGSTRING( "RSearchServerSubSession::UpdateL(): sending the request to server" );
	User::LeaveIfError( SendReceive(ESearchServerUpdate, args) );
	OstTrace0( TRACE_NORMAL, DUP1_RSEARCHSERVERSUBSESSION_UPDATEL, "RSearchServerSubSession::UpdateL(): sent the request to server success" );
	CPIXLOGSTRING( "RSearchServerSubSession::UpdateL(): sent the request to server success" );
	}

// Deletes the document uid in the index
EXPORT_C void RSearchServerSubSession::DeleteL(const TDesC& aDocUid)
	{
	TIpcArgs args(&aDocUid);	
	User::LeaveIfError( SendReceive(ESearchServerDelete, args) );
	}

// Resets all of the documents in the index
EXPORT_C void RSearchServerSubSession::ResetL()
	{
	User::LeaveIfError( SendReceive(ESearchServerReset) );
	}

// Issues CPix flush
EXPORT_C void RSearchServerSubSession::FlushL()
    {
    User::LeaveIfError( SendReceive(ESearchServerFlush) );
    }

// Issues CPix flush
EXPORT_C void RSearchServerSubSession::Flush(TRequestStatus& aStatus)
    {
    SendReceive(ESearchServerFlush, aStatus);
    }


// StartServer()
// Starts the server if it is not already running
static TInt StartServer( const TDesC& aServerName , TUid aServerUid )
	{
	TInt result;

	TFindServer findsearchServer(aServerName);
	TFullName name;

	result = findsearchServer.Next(name);
	if (result == KErrNone)
		{
		// Server already running
		return KErrNone;
		}

	RSemaphore semaphore;
	result = semaphore.CreateGlobal(KSearchServerSemaphoreName, 0);
	if (result != KErrNone)
		{
		return result;
		}

	result = CreateServerProcess( aServerName,aServerUid );
	if (result != KErrNone)
		{
		return result;
		}

	semaphore.Wait();
	semaphore.Close();

	return KErrNone;
	}

// CreateServerProcess()
// Creates a server process
static TInt CreateServerProcess( const TDesC& aServerName , TUid aServerUid )
	{
	TInt result;

	const TUidType serverUid( KNullUid, KNullUid, aServerUid);

	RProcess server;

	result = server.Create(aServerName, KNullDesC, serverUid);
	if (result != KErrNone)
		{
		return result;
		}

	server.Resume();
	server.Close();
	return KErrNone;
	}

// End of File