diff -r 000000000000 -r e686773b3f54 predictivesearch/PcsServerClientAPI/src/CPsRequestHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/predictivesearch/PcsServerClientAPI/src/CPsRequestHandler.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,1287 @@ +/* +* 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: This is the client side interface for the predictive search +* server. +* +*/ + +// SYSTEM INCLUDES +#include +#include +#include + +// USER INCLUDE +#include "CPsPropertyHandler.h" +#include "CPcsDebug.h" +#include "CPsPattern.h" + +// ========================= MEMBER FUNCTIONS ================================== + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::NewL() +// Two-phased constructor. +// ----------------------------------------------------------------------------- +EXPORT_C CPSRequestHandler* CPSRequestHandler::NewL() + { + PRINT ( _L("Enter CPSRequestHandler::NewL") ); + + CPSRequestHandler* self = NewLC(); + CleanupStack::Pop(self); + + PRINT ( _L("End CPSRequestHandler::NewL") ); + + return (self); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::NewLC() +// Two-phased constructor. +// ----------------------------------------------------------------------------- +EXPORT_C CPSRequestHandler* CPSRequestHandler::NewLC() + { + PRINT ( _L("Enter CPSRequestHandler::NewLC") ); + + CPSRequestHandler* self = new (ELeave) CPSRequestHandler(); + CleanupStack::PushL(self); + self->ConstructL(); + + PRINT ( _L("End CPSRequestHandler::NewLC") ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::ConstructL() +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +void CPSRequestHandler::ConstructL() + { + PRINT ( _L("Enter CPSRequestHandler::ConstructL") ); + + User::LeaveIfError(iSession.Connect()); + + // Initiate the property handler + iPropertyHandler = CPsPropertyHandler::NewL(this); + + // Initialize the contact id converter + iConverter = NULL; + + PRINT ( _L("End CPSRequestHandler::ConstructL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::CCSAsyncRequestHandler() +// C++ default constructor can NOT contain any code, that might leave. +// ----------------------------------------------------------------------------- +CPSRequestHandler::CPSRequestHandler() : + CActive(EPriorityStandard) + { + PRINT ( _L("Enter CPSRequestHandler::CPSRequestHandler") ); + + CActiveScheduler::Add(this); + + PRINT ( _L("End CPSRequestHandler::CPSRequestHandler") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::~CPSRequestHandler() +// Destructor. +// ----------------------------------------------------------------------------- +CPSRequestHandler::~CPSRequestHandler() + { + PRINT ( _L("Enter CPSRequestHandler::~CPSRequestHandler") ); + + Cancel(); // Causes call to DoCancel() + + // Close the session + iSession.Close(); + + // Cleanup + if (iSearchQueryBuffer) + { + delete iSearchQueryBuffer; + } + + if (iPendingSearchQueryBuffer) + { + delete iPendingSearchQueryBuffer; + } + + if (iSearchDataBuffer) + { + delete iSearchDataBuffer; + } + + if (iSearchResultsBuffer) + { + delete iSearchResultsBuffer; + iSearchResultsBuffer = NULL; + } + + if (iPropertyHandler) + { + delete iPropertyHandler; + iPropertyHandler = NULL; + } + + if (iConverter) + { + delete iConverter; + iConverter = NULL; + } + + iObservers.Reset(); + iObservers.Close(); + + PRINT ( _L("End CPSRequestHandler::~CPSRequestHandler") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::AddObserverL() +// +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::AddObserverL(MPsResultsObserver* aObserver) + { + iObservers.InsertInAddressOrderL(aObserver); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::RemoveObserver() +// +// ----------------------------------------------------------------------------- +EXPORT_C TInt CPSRequestHandler::RemoveObserver(MPsResultsObserver* aObserver) + { + TInt index = iObservers.FindInAddressOrder(aObserver); + if (index != KErrNotFound) + { + iObservers.Remove(index); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::SetSearchSettingsL() +// Send the search settings to the predictive search engine +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::SetSearchSettingsL(const CPsSettings& aSettings) + { + PRINT ( _L("Enter CPSRequestHandler::SetSearchSettingsL") ); + + // Tmp buffer + CBufFlat *buf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(buf); + + // Stream over the temp buffer + RBufWriteStream stream(*buf); + stream.PushL(); + + // Write the search query to the stream + aSettings.ExternalizeL(stream); + stream.CommitL(); + + // Create a HBufC8 for IPC + HBufC8* settingsBuffer = HBufC8::NewLC(buf->Size()); + TPtr8 ptr(settingsBuffer->Des()); + buf->Read(0, ptr, buf->Size()); + + // Send the settings to the server + iSession.SetSearchSettingsL(settingsBuffer->Des()); + + CleanupStack::PopAndDestroy(3, buf); // buf, stream, settingsBuffer + + PRINT ( _L("End CPSRequestHandler::SetSearchSettingsL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::SearchL() +// Sends a request to the predictive search engine to perform a search. +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::SearchL(const CPsQuery& aSearchQuery) + { + // __LATENCY_MARK ( _L("CPSRequestHandler::SearchL <--- INITIATE SEARCH") ); + PRINT ( _L("Enter CPSRequestHandler::SearchL") ); + + // ----------------------- Search Query ---------------------- + iSearchRequestCancelled = EFalse; + + // Tmp buffer + CBufFlat *buf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(buf); + + // Stream over the temp buffer + RBufWriteStream stream(*buf); + stream.PushL(); + + // Write the search query to the stream + aSearchQuery.ExternalizeL(stream); + stream.CommitL(); + + // If there is no submitted request, then submits the new coming search request + if (!IsActive()) + { + // Create a HBufC8 for IPC + if (iSearchQueryBuffer) + { + delete iSearchQueryBuffer; + iSearchQueryBuffer = NULL; + } + iSearchQueryBuffer = HBufC8::NewLC(buf->Size()); + CleanupStack::Pop(); // iSearchQueryBuffer + TPtr8 ptr(iSearchQueryBuffer->Des()); + buf->Read(0, ptr, buf->Size()); + + // Clear pending search query buffer + if (iPendingSearchQueryBuffer) + { + delete iPendingSearchQueryBuffer; + iPendingSearchQueryBuffer = NULL; + } + + // ------------------------- Results Buffer --------------------- + + // Create a buffer to store the search results. + if (iSearchResultsBuffer) + { + delete iSearchResultsBuffer; + iSearchResultsBuffer = NULL; + } + iSearchResultsBuffer = HBufC8::NewL(KSearchResultsBufferLen); + + // -------------------------------------------------------------- + + // Initiate the search + iSession.SearchL(iSearchQueryBuffer->Des(), iSearchResultsBuffer->Des(), iStatus); + SetActive(); + } + else // else holds it in iPendingSearchQueryBuffer( which will be submitted in HandleSearchResults() ) + { + CancelSearch(); + iPendingSearchQueryBuffer = HBufC8::NewLC(buf->Size()); + CleanupStack::Pop(); + TPtr8 ptr(iPendingSearchQueryBuffer->Des()); + buf->Read(0, ptr, buf->Size()); + } + + CleanupStack::PopAndDestroy(2, buf); // buf, stream + + PRINT ( _L("End CPSRequestHandler::SearchL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::LookupL() +// Sends a request to the predictive search engine to perform a search. +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::LookupL(const CPsQuery& aSearchQuery, + const TDesC& aSearchData, + CDesCArray& aMatchSet, + RArray& aMatchLocation) + { + PRINT ( _L("Enter CPSRequestHandler::LookupL") ); + + // ----------------------- Search Query ---------------------- + + // Tmp buffer + CBufFlat *buf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(buf); + + // Stream over the temp buffer + RBufWriteStream stream(*buf); + stream.PushL(); + + // Write the search query to the stream + aSearchQuery.ExternalizeL(stream); + stream.CommitL(); + + // Create a HBufC8 for IPC + HBufC8* searchQueryBuffer = HBufC8::NewL(buf->Size()); + TPtr8 ptr(searchQueryBuffer->Des()); + buf->Read(0, ptr, buf->Size()); + + CleanupStack::PopAndDestroy(2, buf); // buf, stream + CleanupStack::PushL(searchQueryBuffer); + + // ----------------------- Search Data ---------------------- + + // Tmp buffer + CBufFlat* dataBuf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(dataBuf); + + // Stream over the temp buffer + RBufWriteStream dataStream(*dataBuf); + dataStream.PushL(); + + // Write the search data to the stream + dataStream.WriteUint16L(aSearchData.Size()); + dataStream << aSearchData; + + // Create a HBufC8 for IPC + HBufC8* searchDataBuffer = HBufC8::NewL(dataBuf->Size()); + TPtr8 dataPtr(searchDataBuffer->Des()); + dataBuf->Read(0, dataPtr, dataBuf->Size()); + + CleanupStack::PopAndDestroy(2, dataBuf); // dataBuf, dataStream + CleanupStack::PushL(searchDataBuffer); + + // ------------------------- Results Buffer --------------------- + + // Create a buffer to store the search results. + HBufC8* searchResultsBuffer = HBufC8::NewLC(KBufferMaxLen); + + // -------------------------------------------------------------- + + // Initiate the search + iSession.SearchL(searchQueryBuffer->Des(), searchDataBuffer->Des(), + searchResultsBuffer->Des()); + + // Parse the results + RDesReadStream resultStream(searchResultsBuffer->Des()); + resultStream.PushL(); + + // Number of results + TInt seqCount = resultStream.ReadUint16L(); + + PRINT1 ( _L("CPSRequestHandler::LookupL: Number of search seqs received = %d"), seqCount ); + + // Internalize each char seq + for (int i = 0; i < seqCount; i++) + { + // Size of sequence + TInt szSeq = resultStream.ReadUint16L(); + + // Character sequence + HBufC* seq = HBufC::NewLC(resultStream, szSeq); + + aMatchSet.AppendL(seq->Des()); + + CleanupStack::PopAndDestroy(); + } + + // --------- match sequence location ------------------ + // number of results + TInt count = resultStream.ReadUint16L(); + + // read each data struct + for (TInt k = 0; k < count; k++) + { + TPsMatchLocation matchLoc; + + matchLoc.index = resultStream.ReadUint16L(); + matchLoc.length = resultStream.ReadUint16L(); + matchLoc.direction = (TBidiText::TDirectionality) (resultStream.ReadUint16L()); + + aMatchLocation.Append(matchLoc); + } + + //cleanup + CleanupStack::PopAndDestroy(4, searchQueryBuffer); + // resultStream, searchResultsBuffer, searchDataBuffer, searchQueryBuffer + + PRINT1 ( _L("CPSRequestHandler::LookupL: Search Data: %S"), &aSearchData ); + PRINTMATCHSET ( _L("CPSRequestHandler::LookupL: "), aMatchSet ); + PRINTMATCHLOC ( _L("CPSRequestHandler::LookupL: "), aMatchLocation ); + PRINT ( _L("End CPSRequestHandler::LookupL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::LookupMatchL() +// Sends a request to the predictive search engine to perform a search. +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::LookupMatchL(const CPsQuery& aSearchQuery, + const TDesC& aSearchData, + TDes& aMatch ) + { + PRINT ( _L("Enter CPSRequestHandler::LookupMatchL") ); + + // ----------------------- Search Query ---------------------- + + // Tmp buffer + CBufFlat *buf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(buf); + + // Stream over the temp buffer + RBufWriteStream stream(*buf); + stream.PushL(); + + // Write the search query to the stream + aSearchQuery.ExternalizeL(stream); + stream.CommitL(); + + // Create a HBufC8 for IPC + HBufC8* searchQueryBuffer = HBufC8::NewL(buf->Size()); + TPtr8 ptr(searchQueryBuffer->Des()); + buf->Read(0, ptr, buf->Size()); + + CleanupStack::PopAndDestroy(2, buf); // buf, stream + CleanupStack::PushL(searchQueryBuffer); + + // ----------------------- Search Data ---------------------- + + // Tmp buffer + CBufFlat* dataBuf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(dataBuf); + + // Stream over the temp buffer + RBufWriteStream dataStream(*dataBuf); + dataStream.PushL(); + + // Write the search data to the stream + dataStream.WriteUint16L(aSearchData.Size()); + dataStream << aSearchData; + + // Create a HBufC8 for IPC + HBufC8* searchDataBuffer = HBufC8::NewL(dataBuf->Size()); + TPtr8 dataPtr(searchDataBuffer->Des()); + dataBuf->Read(0, dataPtr, dataBuf->Size()); + + CleanupStack::PopAndDestroy(2, dataBuf); // dataBuf, dataStream + CleanupStack::PushL(searchDataBuffer); + + // Initiate the search + iSession.SearchMatchStringL( + searchQueryBuffer->Des(), searchDataBuffer->Des(), aMatch ); + + //cleanup + CleanupStack::PopAndDestroy(searchDataBuffer); + CleanupStack::PopAndDestroy(searchQueryBuffer); + + PRINT1 ( _L("CPSRequestHandler::LookupMatchL: Search Data: %S"), &aSearchData ); + PRINT1 ( _L("CPSRequestHandler::LookupMatchL: Result Match: %S"), &aMatch ); + PRINT ( _L("End CPSRequestHandler::LookupMatchL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::SearchL() +// Sends a request to the predictive search engine to perform a search. +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::SearchL(const CPsQuery& aSearchQuery, + RPointerArray& aMarkedContacts, + CVPbkContactManager* aContactManager) + { + PRINT ( _L("Enter CPSRequestHandler::SearchL") ); + + // Fire the normal search with the input search query + SearchL(aSearchQuery); + + // Clear the bookmarked contacts if any + iMarkedContacts.Reset(); + + // Copy the contact manager + iBookMarkContactManager = aContactManager; + + // Copy the bookmarked contacts + for (TInt i = 0; i < aMarkedContacts.Count(); i++) + { + iMarkedContacts.Append(aMarkedContacts[i]); + } + + PRINT ( _L("End CPSRequestHandler::SearchL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::CancelSearch() +// Cancels ongoing search. +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::CancelSearch() + { + if( IsActive() ) + { + iSearchRequestCancelled = ETrue; + } + + if( iPendingSearchQueryBuffer ) + { + delete iPendingSearchQueryBuffer; + iPendingSearchQueryBuffer = NULL; + } + + iSession.CancelSearch(); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::HandleSearchResultsL() +// Search is complete. Parse and send the results to the client. +// ----------------------------------------------------------------------------- +void CPSRequestHandler::HandleSearchResultsL() + { + PRINT ( _L("Enter CPSRequestHandler::HandleSearchResultsL") ); + + // No pending search query, process the search result + RPointerArray searchResults; + RPointerArray searchSeqs; + + if( !iSearchResultsBuffer ) + { + return; + } + RDesReadStream stream(iSearchResultsBuffer->Des()); + stream.PushL(); + + // Number of results + TInt count = stream.ReadInt32L(); + + PRINT1 ( _L("CPSRequestHandler::HandleSearchResultsL: Number of search results received = %d"), count ); + + // Internalize each data element + for (int i = 0; i < count; i++) + { + CPsClientData* data = CPsClientData::NewL(); + CleanupStack::PushL(data); + + data->InternalizeL(stream); + + CleanupStack::Pop(data); + searchResults.Append(data); + } + + // Check if book marked contacts are there + TInt nBookmark = 0; + if (iMarkedContacts.Count() != 0) + { + nBookmark = AddMarkedContactsL(searchResults); + } + +#ifdef _DEBUG + for ( TInt i = 0; i < searchResults.Count(); i++ ) + { + for ( TInt j = 0; j < searchResults[i]->DataElementCount(); j++ ) + { + if ( searchResults[i]->Data(j) ) + { + PRINT3 ( _L("CPSRequestHandler::HandleSearchResultsL: Results[%d,%d] = %S"), + i, j, &searchResults[i]->Data(j)->Des() ); + } + } + } +#endif // _DEBUG + + // Read number of character sequences + TInt seqCount = stream.ReadInt32L(); + + PRINT1 ( _L("CPSRequestHandler::HandleSearchResultsL: Number of match sequences received = %d"), seqCount ); + + // Internalize each char seq + for (int i = 0; i < seqCount; i++) + { + CPsPattern* pattern = CPsPattern::NewL(); + CleanupStack::PushL(pattern); + + pattern->InternalizeL(stream); + + CleanupStack::Pop(); + if (pattern->FirstIndex() >= 0) // -1 means that is a Alphabetical sort + { + pattern->SetFirstIndex(pattern->FirstIndex() + nBookmark); + } + searchSeqs.Append(pattern); + } + + CleanupStack::PopAndDestroy(); // stream + + // Pass the results to the observer + for (int i = 0; i < iObservers.Count(); i++) + { + iObservers[i]->HandlePsResultsUpdate(searchResults, searchSeqs); + } + + // Clear all the internal buffers + if (iSearchQueryBuffer) + { + delete iSearchQueryBuffer; + iSearchQueryBuffer = NULL; + } + + if (searchResults.Count()) + { + searchResults.ResetAndDestroy(); + } + + if (searchSeqs.Count()) + { + searchSeqs.ResetAndDestroy(); + } + + if (iSearchResultsBuffer) + { + delete iSearchResultsBuffer; + iSearchResultsBuffer = NULL; + } + + PRINT ( _L("End CPSRequestHandler::HandleSearchResultsL") ); + + // __LATENCY_MARKEND ( _L("CPSRequestHandler::HandleSearchResultsL <--- SEARCH COMPLETE") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::RunSearchFromBufferL() +// Runs search if search query buffer ( iPendingSearchQueryBuffer ) is not empty +// ----------------------------------------------------------------------------- +void CPSRequestHandler::RunSearchFromBufferL() + { + PRINT ( _L("Enter CPSRequestHandler::RunSearchFromBufferL") ); + + if( iPendingSearchQueryBuffer ) + { + if (iSearchQueryBuffer) + { + delete iSearchQueryBuffer; + iSearchQueryBuffer = NULL; + } + iSearchQueryBuffer = HBufC8::NewLC(iPendingSearchQueryBuffer->Size()); + CleanupStack::Pop(); + iSearchQueryBuffer->Des().Copy(iPendingSearchQueryBuffer->Des()); + + delete iPendingSearchQueryBuffer; + iPendingSearchQueryBuffer = NULL; + + // ------------------------- Results Buffer --------------------- + + // Create a buffer to store the search results. + if (iSearchResultsBuffer) + { + delete iSearchResultsBuffer; + iSearchResultsBuffer = NULL; + } + iSearchResultsBuffer = HBufC8::NewL(KSearchResultsBufferLen); + + // -------------------------------------------------------------- + + // Initiate the search + iSession.SearchL(iSearchQueryBuffer->Des(), iSearchResultsBuffer->Des(), iStatus); + + SetActive(); + } + + + PRINT ( _L("End CPSRequestHandler::RunSearchFromBufferL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::AddBookMarkedContacts() +// Adds the necessary bookmark contacts to the search result set +// ----------------------------------------------------------------------------- +TInt CPSRequestHandler::AddMarkedContactsL(RPointerArray& searchResults) + { + __LATENCY_MARK ( _L(" CPSRequestHandler::AddMarkedContactsL") ); + PRINT ( _L("Enter CPSRequestHandler::AddMarkedContactsL") ); + + RPointerArray filteredBookMarkList; // Local array to store the filtered bookmark contacts + TInt nBookmark = 0; + + for (TInt i = 0; i < iMarkedContacts.Count(); i++) + { + MVPbkContactLink* bookMarkLink = NULL; + + // See if this contact is already in the result set + TInt id = iMarkedContacts[i]->Id(); + + TInt j = 0; + for (; j < searchResults.Count(); j++) + { + if (id > 0) + { + if (id == searchResults[j]->Id()) + { + searchResults[j]->SetMark(); // Set the bookmark + break; // Found, go to the next bookmark contact + } + else + { + continue; + } + } + else + { + if (searchResults[j]->Id() > 0) + { + continue; + } + else + { + if (!bookMarkLink) + { + bookMarkLink = ConvertToVpbkLinkLC(*(iMarkedContacts[i]), + *iBookMarkContactManager); + CleanupStack::Pop(); // bookMarkLink + } + + MVPbkContactLink* searchContactLink = ConvertToVpbkLinkLC(*(searchResults[j]), + *iBookMarkContactManager); + CleanupStack::Pop(); // searchContactLink + + if (bookMarkLink->IsSame(*searchContactLink)) + { + searchResults[j]->SetMark(); // Set the bookmark + break; // Found, go to the next bookmark contact + } + else + continue; + } + } + } + if (j == searchResults.Count()) // Not found in the result set, Add it + { + filteredBookMarkList.Append(iMarkedContacts[i]); + } + } + + // Create the new CPsClientData objects for each filtered results + // and prepend them to the actual result set + // in reverse order so that they will be in sorted order among themselves + + nBookmark = filteredBookMarkList.Count(); + for (TInt i = filteredBookMarkList.Count() - 1; i >= 0; i--) + { + CPsClientData* temp = CPsClientData::NewL(); + temp->SetId(filteredBookMarkList[i]->Id()); + temp->SetUriL(filteredBookMarkList[i]->Uri()->Des()); + + // Add the data fields + for (TInt j = 0; j < filteredBookMarkList[i]->DataElementCount(); j++) + { + temp->SetDataL(j, filteredBookMarkList[i]->Data(j)->Des()); + } + + temp->SetDataExtensionL(filteredBookMarkList[i]->DataExtension()); + temp->SetMark(); // Set the bookmark + + searchResults.Insert(temp, 0); + } + + // Free the bookmark arrays + iMarkedContacts.Reset(); + filteredBookMarkList.Reset(); + + PRINT ( _L("END CPSRequestHandler::AddMarkedContactsL") ); + __LATENCY_MARKEND ( _L(" CPSRequestHandler::AddMarkedContactsL") ); + return nBookmark; + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::HandleBufferOverFlowL() +// Handle the buffer overflow error +// ----------------------------------------------------------------------------- +void CPSRequestHandler::HandleBufferOverFlowL() + { + PRINT ( _L("Enter CPSRequestHandler::HandleBufferOverFlowL") ); + + // New buffer size is now stored in results buffer + RDesReadStream stream(iSearchResultsBuffer->Des()); + stream.PushL(); + + // Read the buffer size and create a new buffer + TInt bufferSize = stream.ReadInt32L(); + + CleanupStack::PopAndDestroy(); // stream + + // Delete and recreate the results buffer + if (iSearchResultsBuffer) + { + delete iSearchResultsBuffer; + iSearchResultsBuffer = NULL; + } + + // Buffer created for the new size + iSearchResultsBuffer = HBufC8::NewL(bufferSize); + + // Recover the search results + iSession.SendNewBufferL(iSearchResultsBuffer->Des(), iStatus); + + SetActive(); + + PRINT ( _L("End CPSRequestHandler::HandleBufferOverFlowL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::RunL() +// Invoked to handle responses from the server. +// ----------------------------------------------------------------------------- +void CPSRequestHandler::RunL() + { + switch (iStatus.Int()) + { + case ESearchComplete: + // The server has completed the request, signalled the client + // thread and the clients active scheduler runs the active object. + // Now send the search results over the observer interface. + // If request was canceled we will do search from buffer. + if( iSearchRequestCancelled ) + { + RunSearchFromBufferL(); + } + else + { + HandleSearchResultsL(); + } + break; + + case KErrOverflow: + // Internal buffer used for IPC is in-adequate as the match results + // are more. Send a new buffer to recover the results. + // If request was canceled we will do search from buffer. + if( iSearchRequestCancelled ) + { + RunSearchFromBufferL(); + } + else + { + HandleBufferOverFlowL(); + } + break; + + case ECancelComplete: + case KErrCancel: + // The search request was canceled + if( iPendingSearchQueryBuffer ) + { + RunSearchFromBufferL(); + } + break; + + default: + // Errors + HandleErrorL(iStatus.Int()); + } + iSearchRequestCancelled = EFalse; + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::HandleErrorL() +// Send the error code to the client. +// ----------------------------------------------------------------------------- +void CPSRequestHandler::HandleErrorL(TInt aErrorCode) + { + for (int i = 0; i < iObservers.Count(); i++) + { + iObservers[i]->HandlePsError(aErrorCode); + } + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::DoCancel() +// Cancels any outstanding operation. +// ----------------------------------------------------------------------------- +void CPSRequestHandler::DoCancel() + { + iSession.CancelSearch(); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::Version() +// Recovers the predictive search server version. +// ----------------------------------------------------------------------------- +EXPORT_C TVersion CPSRequestHandler::Version() const + { + return (iSession.Version()); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::ShutdownServerL() +// Shuts down the predictive search engine. +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::ShutdownServerL() + { + return (iSession.ShutdownServerL()); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::IsLanguageSupportedL() +// Checks if the language variant is supported by +// the predictive search engine. +// ----------------------------------------------------------------------------- +EXPORT_C TBool CPSRequestHandler::IsLanguageSupportedL(const TLanguage aLanguage) + { + PRINT ( _L("Enter CPSRequestHandler::IsLanguageSupportedL") ); + + // ----------------------- language id---------------------- + + // Tmp buffer + CBufFlat* dataBuf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(dataBuf); + + // Stream over the temp buffer + RBufWriteStream dataStream(*dataBuf); + dataStream.PushL(); + + // Write the language id to the stream + dataStream.WriteUint32L(aLanguage); + + // Create a HBufC8 for IPC + if (iSearchDataBuffer) + { + delete iSearchDataBuffer; + iSearchDataBuffer = NULL; + } + + iSearchDataBuffer = HBufC8::NewLC(dataBuf->Size()); + CleanupStack::Pop(); // iSearchDataBuffer + TPtr8 dataPtr(iSearchDataBuffer->Des()); + dataBuf->Read(0, dataPtr, dataBuf->Size()); + + CleanupStack::PopAndDestroy(2, dataBuf); // dataBuf, dataStream + + // ------------------------- Results Buffer --------------------- + + // Create a buffer to store the search results. + if (iSearchResultsBuffer) + { + delete iSearchResultsBuffer; + iSearchResultsBuffer = NULL; + } + iSearchResultsBuffer = HBufC8::NewL(KBufferMaxLen); + + // -------------------------------------------------------------- + // Send the request + iSession.IsLanguageSupportedL(iSearchDataBuffer->Des(), iSearchResultsBuffer->Des()); + + // parse the result + RDesReadStream resultStream(iSearchResultsBuffer->Des()); + resultStream.PushL(); + + // result ETrue or EFalse + TBool flag = resultStream.ReadUint8L(); + + CleanupStack::PopAndDestroy(); // resultStream + + PRINT ( _L("End CPSRequestHandler::IsLanguageSupportedL") ); + return flag; + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::GetCachingStatusL() +// Gets the status of the caching synchronously +// ----------------------------------------------------------------------------- +EXPORT_C TInt CPSRequestHandler::GetCachingStatusL(TCachingStatus& aStatus) + { + PRINT ( _L("Enter CPSRequestHandler::GetCachingStatusL") ); + + // Get the status from property handler + // No need to send the request to engine + TInt cacheError = iPropertyHandler->GetCachingStatusL(aStatus); + + PRINT ( _L("End CPSRequestHandler::GetCachingStatusL") ); + return cacheError; + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::ConvertToVpbkLinkLC() +// Get the contact link associated with the search result +// ----------------------------------------------------------------------------- +EXPORT_C MVPbkContactLink* CPSRequestHandler::ConvertToVpbkLinkLC(const CPsClientData& aPsData, + CVPbkContactManager& aContactManager) + { + PRINT ( _L("Enter CPSRequestHandler::ConvertToVpbkLinkLC") ); + + MVPbkContactLink* contactLink = NULL; + + // Get the originating uri for this result + HBufC* URI = aPsData.Uri(); + + // Leave if not in contacts domain + if (URI->CompareC(KVPbkDefaultCntDbURI) != 0 && URI->CompareC(KVPbkSimGlobalAdnURI) != 0 \ + && URI->CompareC(KVPbkSimGlobalFdnURI) != 0 && URI->CompareC(KVPbkSimGlobalSdnURI) != 0 + && URI->CompareC(KVPbkDefaultGrpDbURI) != 0) + { + User::Leave(KErrNotSupported); + } + + // Create converter instance if not already available + if (iConverter == NULL) + { + // Get the store corresponding to the URI + MVPbkContactStoreList& storeList = aContactManager.ContactStoresL(); + TVPbkContactStoreUriPtr uriPtr(KVPbkDefaultCntDbURI); + MVPbkContactStore* store = storeList.Find(uriPtr); + + // Create converter + if (store) + { + iConverter = CVPbkContactIdConverter::NewL(*store); + } + } + + if (aPsData.Id() < 0) // ID is negative for contacts in SIM domain + { + // Contact link is already packed for SIM contacts in CPsClientData + HBufC8* linkBuf = (HBufC8*) aPsData.DataExtension(); + + // ---------------- Convert HBufC8* to contact link --------------------------- + + if (linkBuf->Length()) + { + // Get the store corresponding to the URI + MVPbkContactStoreList& storeList = aContactManager.ContactStoresL(); + + // Link array + CVPbkContactLinkArray* array = CVPbkContactLinkArray::NewLC(*(linkBuf), storeList); + + TInt count = array->Count(); + + if (count == 1) // should contain only single contact link + { + const MVPbkContactLink& link = array->At(0); + contactLink = link.CloneLC(); + CleanupStack::Pop(); // contactLink + } + + CleanupStack::PopAndDestroy(); // array + } + + // ---------------- End convert HBufC8* to contact link ----------------------- + } + else + { + // cntdb domain + if (iConverter) + { + contactLink = iConverter->IdentifierToLinkLC(aPsData.Id()); + CleanupStack::Pop(); + } + } + + // Add to cleanup stack + CleanupDeletePushL(contactLink); + + PRINT ( _L("End CPSRequestHandler::ConvertToVpbkLinkLC") ); + + return contactLink; + + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::GetAllContentsL() +// Sends a request to the predictive search server to get all cached contents. +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::GetAllContentsL() + { + PRINT ( _L("Enter CPSRequestHandler::GetAllContentsL") ); + + // Create a empty CPsQuery + CPsQuery* query = CPsQuery::NewL(); + + // Perform a search + SearchL(*query); + + // Cleanup + delete query; + + PRINT ( _L("Enter CPSRequestHandler::GetAllContentsL") ); + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::GetDataOrderL() +// +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::GetDataOrderL(const TDesC& aURI, + RArray& aDataOrder) + { + PRINT ( _L("Enter CPSRequestHandler::GetDataOrderL") ); + + // ----------------------- URI ---------------------- + + // Tmp buffer + CBufFlat* dataBuf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(dataBuf); + + // Stream over the temp buffer + RBufWriteStream dataStream(*dataBuf); + dataStream.PushL(); + + // Write the URI details in the stream + TInt length = aURI.Length(); + dataStream.WriteUint16L(length); + dataStream << aURI; + + // Create a HBufC8 for IPC + if (iSearchDataBuffer) + { + delete iSearchDataBuffer; + iSearchDataBuffer = NULL; + } + + iSearchDataBuffer = HBufC8::NewL(dataBuf->Size()); + TPtr8 dataPtr(iSearchDataBuffer->Des()); + dataBuf->Read(0, dataPtr, dataBuf->Size()); + + // ------------------------- Results Buffer --------------------- + + // Create a buffer to store the search results. + if (iSearchResultsBuffer) + { + delete iSearchResultsBuffer; + iSearchResultsBuffer = NULL; + } + iSearchResultsBuffer = HBufC8::NewL(KBufferMaxLen); + + // -------------------------------------------------------------- + + // Send the request + iSession.GetDataOrderL(iSearchDataBuffer->Des(), iSearchResultsBuffer->Des()); + + // Parse the results + RDesReadStream resultStream(iSearchResultsBuffer->Des()); + resultStream.PushL(); + + // Number of fields + TInt fieldCount = resultStream.ReadUint16L(); + + // Fields + for (int i = 0; i < fieldCount; i++) + { + TInt fieldId = resultStream.ReadUint16L(); + aDataOrder.Append(fieldId); + } + + // Cleanup + delete iSearchResultsBuffer; + delete iSearchDataBuffer; + CleanupStack::PopAndDestroy(3, dataBuf); // resultStream, dataStream, dataBuf + iSearchResultsBuffer = NULL; + iSearchDataBuffer = NULL; + + PRINT ( _L("End CPSRequestHandler::GetDataOrderL") ); + + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::GetSortOrderL() +// +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::GetSortOrderL(const TDesC& aURI, RArray& aDataOrder) + { + PRINT ( _L("Enter CPSRequestHandler::GetSortOrderL") ); + + // ----------------------- URI ---------------------- + + // Tmp buffer + CBufFlat* dataBuf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(dataBuf); + + // Stream over the temp buffer + RBufWriteStream dataStream(*dataBuf); + dataStream.PushL(); + + // Write the URI details in the stream + TInt length = aURI.Length(); + dataStream.WriteUint16L(length); + dataStream << aURI; + + // Create a HBufC8 for IPC + if (iSearchDataBuffer) + { + delete iSearchDataBuffer; + iSearchDataBuffer = NULL; + } + + iSearchDataBuffer = HBufC8::NewL(dataBuf->Size()); + TPtr8 dataPtr(iSearchDataBuffer->Des()); + dataBuf->Read(0, dataPtr, dataBuf->Size()); + + // ------------------------- Results Buffer --------------------- + + // Create a buffer to store the search results. + if (iSearchResultsBuffer) + { + delete iSearchResultsBuffer; + iSearchResultsBuffer = NULL; + } + iSearchResultsBuffer = HBufC8::NewL(KBufferMaxLen); + + // -------------------------------------------------------------- + + // Send the request + iSession.GetSortOrderL(iSearchDataBuffer->Des(), iSearchResultsBuffer->Des()); + + // Parse the results + RDesReadStream resultStream(iSearchResultsBuffer->Des()); + resultStream.PushL(); + + // Number of fields + TInt fieldCount = resultStream.ReadUint16L(); + + // Fields + for (int i = 0; i < fieldCount; i++) + { + TInt fieldId = resultStream.ReadUint16L(); + aDataOrder.Append(fieldId); + } + + // Cleanup + delete iSearchResultsBuffer; + delete iSearchDataBuffer; + CleanupStack::PopAndDestroy(3, dataBuf); // resultStream, dataStream, dataBuf + iSearchResultsBuffer = NULL; + iSearchDataBuffer = NULL; + + PRINT ( _L("End CPSRequestHandler::GetSortOrderL") ); + + } + +// ----------------------------------------------------------------------------- +// CPSRequestHandler::ChangeSortOrderL() +// +// ----------------------------------------------------------------------------- +EXPORT_C void CPSRequestHandler::ChangeSortOrderL(const TDesC& aURI, RArray& aSortOrder) + { + PRINT ( _L("Enter CPSRequestHandler::ChangeSortOrderL") ); + + // ----------------------- URI and Sort Order -------------------- + + // Tmp buffer + CBufFlat* dataBuf = CBufFlat::NewL(KBufferMaxLen); + CleanupStack::PushL(dataBuf); + + // Stream over the temp buffer + RBufWriteStream dataStream(*dataBuf); + dataStream.PushL(); + + // Write the URI details in the stream + TInt length = aURI.Length(); + dataStream.WriteUint16L(length); + dataStream << aURI; + + // Write the sort order + dataStream.WriteUint16L(aSortOrder.Count()); + for (int i = 0; i < aSortOrder.Count(); i++) + { + dataStream.WriteUint16L(aSortOrder[i]); + } + + // Create a HBufC8 for IPC + if (iSearchDataBuffer) + { + delete iSearchDataBuffer; + iSearchDataBuffer = NULL; + } + + iSearchDataBuffer = HBufC8::NewL(dataBuf->Size()); + TPtr8 dataPtr(iSearchDataBuffer->Des()); + dataBuf->Read(0, dataPtr, dataBuf->Size()); + + // Send the request + iSession.ChangeSortOrderL(iSearchDataBuffer->Des()); + + // Cleanup + delete iSearchDataBuffer; + CleanupStack::PopAndDestroy(2, dataBuf); // dataStream, dataBuf + iSearchDataBuffer = NULL; + + PRINT ( _L("End CPSRequestHandler::ChangeSortOrderL") ); + + } + +// End of File