diff -r 6b5524b4f673 -r 38bb213f60ba predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2MultiSearchHelper.cpp --- a/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2MultiSearchHelper.cpp Wed Sep 15 11:56:55 2010 +0300 +++ b/predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2MultiSearchHelper.cpp Wed Oct 13 14:15:33 2010 +0300 @@ -23,7 +23,26 @@ #include #include +// Compare functions +TBool Compare2(const HBufC& aFirst, const HBufC& aSecond) + { + TPtrC t1(aFirst); + TPtrC t2(aSecond); + return (t1.Length() > t2.Length()); + } +TBool Compare3(const TDesC& aFirst, const TDesC& aSecond) + { + return aFirst == aSecond; + } + +TBool Compare4(const CPsQuery& aFirst, const CPsQuery& aSecond) + { + CPsQuery& first = const_cast (aFirst); + CPsQuery& second = const_cast (aSecond); + + return (first.Count() > second.Count()); + } // ============================== MEMBER FUNCTIONS ============================ // ---------------------------------------------------------------------------- @@ -63,14 +82,13 @@ PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::ConstructL") ); iAlgorithm = aAlgorithm; - iKeyMap = iAlgorithm->GetKeyMap(); - iMaxCount = 0; - + keyMap = iAlgorithm->GetKeyMap(); + PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::ConstructL") ); } // ---------------------------------------------------------------------------- -// CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper +// CPcsAlgorithm2MultiSearchHelper::CPcsAlgorithm2MultiSearchHelper // Destructor // ---------------------------------------------------------------------------- CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper() @@ -98,105 +116,90 @@ // ---------------------------------------------------------------------------- void CPcsAlgorithm2MultiSearchHelper::SearchMultiL(const CPsSettings& aSettings, RPointerArray& aPsQuery, - TBool aIsSearchInGroup, - const RArray& aContactsInGroup, - RPointerArray& aSearchResults, - RPointerArray& aSearchSeqs) + TBool isSearchInGroup, + RArray& aContactsInGroup, + RPointerArray& searchResults, + RPointerArray& searchSeqs, + TInt keyboardMode) { + __LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") ); PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMultiL") ); - //__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") ); - - PRINTQUERYLIST ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL: "), aPsQuery ); - - iMaxCount = aSettings.MaxResults(); // Create CPcsAlgorithm2FilterHelper object to be used for filtering the results TSortType sortType = aSettings.GetSortType(); CPcsAlgorithm2FilterHelper* filterHelper = CPcsAlgorithm2FilterHelper::NewL(sortType); - CleanupStack::PushL( filterHelper ); RPointerArray elements; - CleanupClosePushL( elements ); iMultiSearchResultsArr.ResetAndDestroy(); // Get the data stores - RPointerArray dataStores; - CleanupResetAndDestroyPushL( dataStores ); - aSettings.SearchUrisL(dataStores); + RPointerArray aDataStores; + aSettings.SearchUrisL(aDataStores); // Get the required display fields from the client RArray requiredDataFields; - CleanupClosePushL( requiredDataFields ); aSettings.DisplayFieldsL(requiredDataFields); - // Search from cache based on first character of 1st item in query list + // Search from cache based on first character const CPsQueryItem& firstCharItem = aPsQuery[0]->GetItemAtL(0); - TInt cachePoolId = iKeyMap->PoolIdForCharacter( firstCharItem.Character(), firstCharItem.Mode() ); - + TInt numValue = keyMap->PoolIdForCharacter( firstCharItem.Character() ); + // Get the elements from all the databases - const TInt dataStoresCount = dataStores.Count(); - for (TInt dsIndex = 0; dsIndex < dataStoresCount; dsIndex++) + for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++) { RPointerArray *temp = new (ELeave) RPointerArray (); iMultiSearchResultsArr.Append(temp); // Get the contents for this data store - TInt arrayIndex = iAlgorithm->GetCacheIndex(*(dataStores[dsIndex])); + TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex])); if (arrayIndex < 0) { continue; } CPcsCache* cache = iAlgorithm->GetCache(arrayIndex); - cache->GetContactsForKeyL(cachePoolId, elements); + cache->GetContactsForKeyL(numValue, elements); // Get the supported data fields for this data store RArray supportedDataFields; - CleanupClosePushL( supportedDataFields ); cache->GetDataFields(supportedDataFields); - // Get the filtered data fields for this data store - TUint8 filteredDataMatch = CPcsAlgorithm2Utils::FilterDataFieldsL( - requiredDataFields, supportedDataFields); + // Get the filtered data fields for this data store + TUint8 filteredDataMatch = FilterDataFieldsL(requiredDataFields, supportedDataFields); // Filter the results now - FilterResultsMultiL(filterHelper, - elements, - aPsQuery, - filteredDataMatch, - aIsSearchInGroup, - aContactsInGroup); + FilterResultsMultiL(filterHelper, elements, aPsQuery, filteredDataMatch, + isSearchInGroup, aContactsInGroup, keyboardMode); - // If alphabetical sorting, get the results for this datastore + // If alphabetical sorting, get the results for this datastore if (sortType == EAlphabetical) { filterHelper->GetResults(*(iMultiSearchResultsArr[dsIndex])); } elements.Reset(); - CleanupStack::PopAndDestroy( &supportedDataFields ); // Close + supportedDataFields.Reset(); } - CleanupStack::PopAndDestroy( &requiredDataFields ); // Close - CleanupStack::PopAndDestroy( &dataStores ); // ResetAndDestroy + aDataStores.ResetAndDestroy(); + requiredDataFields.Reset(); // If alphabetical sorting, merge the result sets of all datastores if (sortType == EAlphabetical) { // Form the complete searchResults array - CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr, - aSearchResults); + CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr, searchResults); } else { // Results are already sorted patternbased - filterHelper->GetResults(aSearchResults); + filterHelper->GetResults(searchResults); } // Get the sorted match sequence list - filterHelper->GetPatternsL(aSearchSeqs); + filterHelper->GetPatternsL(searchSeqs); - PRINT1 ( _L("Number of search results = %d"), aSearchResults.Count() ); + PRINT1 ( _L("Number of search results = %d"), searchResults.Count() ); - // Cleanup + // Cleanup for (TInt i = 0; i < iMultiSearchResultsArr.Count(); i++) { iMultiSearchResultsArr[i]->Reset(); @@ -205,197 +208,214 @@ } iMultiSearchResultsArr.Reset(); - CleanupStack::PopAndDestroy( &elements ); // Close - CleanupStack::PopAndDestroy( filterHelper ); - - //__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") ); + delete filterHelper; PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMultiL") ); + __LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") ); } // ---------------------------------------------------------------------------- -// CPcsAlgorithm1MultiSearchHelper::SearchMatchSeqMultiL -// Function adds matches, and locations based on multi query, and data -// Duplicate locations are allowed (as they are removed later anyway) -// Post condition locations in index order +// CPcsAlgorithm2MultiSearchHelper::SearchInputMultiL +// Function to search match sequences for multi query // ---------------------------------------------------------------------------- -void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL( RPointerArray& aPsQuery, - const TDesC& aData, - RPointerArray& aMatchSeq, - RArray& aMatchLocation ) +void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL(RPointerArray& aPsQuery, + TDesC& aData, + RPointerArray& aMatchSet, + RArray& aMatchLocation) { PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") ); - - TLex lex(aData); - while ( !lex.Eos() ) // Search thru all words - { - TPtrC currentWord = lex.NextToken(); // next word - - const TInt psQueryCount = aPsQuery.Count(); - for ( TInt queryIndex = 0; queryIndex < psQueryCount; ++queryIndex ) - { - CPsQuery* currentQuery = aPsQuery[queryIndex]; - - RArray matchPos; - CleanupClosePushL( matchPos ); - RArray matchLen; - CleanupClosePushL( matchLen ); - - if ( iAlgorithm->FindUtilECE()->MatchRefineL( currentWord, *currentQuery, matchPos, matchLen, ETrue ) ) - { - // Some matches found. Add all of them to result array. - ASSERT( matchPos.Count() == matchLen.Count() ); - - TInt wordStartPos = lex.Offset() - currentWord.Length(); - const TInt matchPosCount = matchPos.Count(); - for ( TInt i = 0 ; i < matchPosCount; ++i ) - { - TPsMatchLocation newLocation = { wordStartPos + matchPos[i], matchLen[i], - TBidiText::TextDirectionality(currentWord) }; - aMatchLocation.AppendL( newLocation ); + CleanupResetAndDestroyPushL( aMatchSet ); + CleanupClosePushL( aMatchLocation ); + + RPointerArray queryList; + ConvertQueryToListL(aPsQuery, queryList); - TPtrC matchPart = currentWord.Mid( matchPos[i], matchLen[i] ); - CPcsAlgorithm2Utils::AppendMatchToSeqL( aMatchSeq, matchPart ); - } - } - - CleanupStack::PopAndDestroy( &matchLen ); - CleanupStack::PopAndDestroy( &matchPos ); - } + RPointerArray tempqueryList; + // Remember a temporary copy of query list + // since we sort the queries + for (TInt i = 0; i < queryList.Count(); i++) + { + tempqueryList.Append(queryList[i]); } - - PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") ); - } - -// ---------------------------------------------------------------------------- -// CPcsAlgorithm2MultiSearchHelper::LookupMatchL -// ---------------------------------------------------------------------------- -void CPcsAlgorithm2MultiSearchHelper::LookupMatchL( CPsQuery& aSearchQuery, - const TDesC& aData, TDes& aMatchedData ) - { - _LIT( KSpace, " " ); - aMatchedData.Zero(); - RPointerArray queryList = MultiQueryL( aSearchQuery ); - CleanupResetAndDestroyPushL( queryList ); - // Convert the individual queries to string form - RPointerArray mySearchQuery; - CleanupResetAndDestroyPushL( mySearchQuery ); - - // Remember a temporary copy of query list - // Copy the content of searchQuery - const TInt searchQueryCount = queryList.Count(); - for (TInt i = 0; i < searchQueryCount; i++ ) - { - CPsQuery* tempQuery = CPsQuery::NewL(); - CleanupStack::PushL( tempQuery ); - iAlgorithm->FindUtilECE()->GetPartOfQueryL( *(queryList[i]), 0, - queryList[i]->Count() - 1, *tempQuery ); - mySearchQuery.AppendL( tempQuery ); - CleanupStack::Pop( tempQuery ); // ownership transferred - } - - // Sort the query items according to the length of each query - TLinearOrder rule( CPcsAlgorithm2Utils::CompareLength ); - mySearchQuery.Sort( rule ); - // To hold the match results RPointerArray tmpMatchSet; - CleanupResetAndDestroyPushL( tmpMatchSet ); + TBool isMatch = ETrue; + TUint32 wordMatches = 0; - TBool isMatch = ETrue; - TInt wordMatches = 0; - - // Reset iWordMatches to zero - ClearWordMatches(); + // Sort the query items before we search them + TLinearOrder rule(Compare2); + queryList.Sort(rule); // Check for each query atleast one data element matches // Loop from the last query so that longest match is seen first - for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex-- ) + for (TInt queryIndex = queryList.Count() - 1; queryIndex >= 0; queryIndex--) { TBool queryMatch = EFalse; - CPsQuery* tmpPsQuery = mySearchQuery[queryIndex]; + HBufC* tmpQuery = queryList[queryIndex]; + // Get the original query mode corresponding to this query + TInt modeIndex = tempqueryList.Find(tmpQuery); - TInt wordIndex = -1; - TLex lex( aData ); + TLex lex(aData); // First word TPtrC tmpData = lex.NextToken(); + TInt beg = lex.Offset() - tmpData.Length(); // start index of match sequence + + TInt wordIndex = -1; // Search thru multiple words - while (tmpData.Length() != 0 ) + while ((tmpData.Length() != 0) && (!queryMatch)) { wordIndex++; - // Compare the data against query - TBool matched = iAlgorithm->FindUtilECE()->MatchRefineL( tmpData, - *tmpPsQuery ); + TPtr ptr = tmpQuery->Des(); - if ( matched ) + // Perform two checks. + // 1. Ensure that the word is not matched against any previous query + // 2. If it is the first match to the query + TBool isWordMatch = EFalse; + TReal val; + Math::Pow(val, 2, wordIndex); + isWordMatch = wordMatches & (TUint) val; + + if (!isWordMatch) { - // Perform two checks. - // 1. Ensure that the word is not matched against any previous query - // 2. If it is the first match to the query - TBool isWordMatch = IsWordMatch( 0, wordIndex ); - - // Check if the current word is not matched to any query - // For example, there is a contact named "abc a" and query is key2 - // The key2 could match the first and second 'a'. So it is required to - // check if the current word has aready been matched before. - - if ( !isWordMatch ) + // Check if no word is matched till now for this query + if (!queryMatch) { - // Check if no word is matched for this query till now - if ( !queryMatch ) - { - wordMatches++; - queryMatch = ETrue; - SetWordMap( 0, wordIndex ); - // Extract matched character sequence and fill in temp array - TInt len = tmpPsQuery->Count(); - if ( iAlgorithm->FindUtilECE()->IsChineseWordIncluded( - tmpData ) ) - { - // A Chinese word could be matched by serveral keys - // It is hard to know the matched query length. So set it to 1 - // as a trick result - len = 1; - } + queryMatch = ETrue; + //set the word match bit + TReal val; + Math::Pow(val, 2, wordIndex); + wordMatches |= (TUint) val; + } + + TPsMatchLocation tempLocation; + // check for directionality of the text + TBool found(EFalse); + TBidiText::TDirectionality dir = TBidiText::TextDirectionality(tmpData, &found); - TPtrC seq = tmpData.Left( len ); - CPcsAlgorithm2Utils::AppendMatchToSeqL( tmpMatchSet, - seq ); - } - } + tempLocation.index = beg; + tempLocation.length = 0; + tempLocation.direction = dir; + + // Add the match location to the data structure array + aMatchLocation.Append(tempLocation); } + } + // Next word + tmpData.Set(lex.NextToken()); + beg = lex.Offset() - tmpData.Length(); // start index of next word - // Next word - tmpData.Set( lex.NextToken() ); - } // No data element matches the query. Ignore this result. - if ( queryMatch == EFalse ) + if (queryMatch == EFalse) { isMatch = EFalse; break; } } + // Count the number of bits set + TInt matchCount = 0; + matchCount = BitsSet32(wordMatches); + // If match add the element to the result set - // And before adding to the result set, check if there is atleast one match per query - if ( isMatch && wordMatches >= mySearchQuery.Count() ) + // Before adding to the result set, check if there is atleast one match per query + // Number of bits set in word matches is atleast equal to total number of queries. + if ((isMatch) && (matchCount >= queryList.Count())) { - const TInt matchCount = tmpMatchSet.Count(); - for (TInt i = 0; i < matchCount; i++ ) + + // Include the match sequences in the final results + for (int i = 0; i < tmpMatchSet.Count(); i++) { - aMatchedData.Append( *tmpMatchSet[i] ); - aMatchedData.Append( KSpace ); + TIdentityRelation rule(Compare3); + CleanupStack::PushL(tmpMatchSet[i]); + if (aMatchSet.Find(tmpMatchSet[i], rule) == KErrNotFound) + { + aMatchSet.Append(tmpMatchSet[i]); + CleanupStack::Pop(); + } + else + { + CleanupStack::PopAndDestroy(); + } } - aMatchedData.TrimRight(); + + // Reset tmp match set + tmpMatchSet.Reset(); + } + else + { + tmpMatchSet.ResetAndDestroy(); } - CleanupStack::PopAndDestroy( &tmpMatchSet ); // ResetAndDestroy - CleanupStack::PopAndDestroy( &mySearchQuery ); // ResetAndDestroy - CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy + // Free the query list + queryList.ResetAndDestroy(); + tempqueryList.Reset(); + + CleanupStack::Pop(); + CleanupStack::Pop( &aMatchSet ); + + PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") ); + } + +// ---------------------------------------------------------------------------- +// CPcsAlgorithm2MultiSearchHelper::ConvertQueryToList +// Converts the multiple search queries to a list +// ---------------------------------------------------------------------------- +void CPcsAlgorithm2MultiSearchHelper::ConvertQueryToListL(RPointerArray& aSearchQuery, + RPointerArray& aQueryList) + { + for (int queryIndex = 0; queryIndex < aSearchQuery.Count(); queryIndex++) + { + CPsQuery* query = aSearchQuery[queryIndex]; + + HBufC* tmpSearchQuery = HBufC::NewL(KPsQueryMaxLen); + TPtr ptr = tmpSearchQuery->Des(); + + if (query->KeyboardModeL() == EItut) // ITU + { + keyMap->GetNumericKeyString(query->QueryAsStringLC(), ptr); + CleanupStack::PopAndDestroy(); + } + else if (query->KeyboardModeL() == EQwerty) // QWERTY + { + ptr = query->QueryAsStringLC(); + ptr.LowerCase(); + CleanupStack::PopAndDestroy(); + } + else // UNDEFINED + { + ExtractQueryL(*query, ptr); + ptr.LowerCase(); + } + aQueryList.Append(tmpSearchQuery); + } + } + +// ---------------------------------------------------------------------------- +// CPcsAlgorithm2MultiSearchHelper::ConvertdDataToKeyBoardModeL +// Converts the input data to the key board mode specified by the query +// ---------------------------------------------------------------------------- +void CPcsAlgorithm2MultiSearchHelper::ConvertdDataToKeyBoardModeL(CPsQuery* aQuery, + TPtrC aInputData, + TBuf& aOutputData) + { + if (aQuery->KeyboardModeL() == EItut) + { + keyMap->GetNumericKeyString(aInputData, aOutputData); + } + else if (aQuery->KeyboardModeL() == EQwerty) + { + aOutputData = aInputData; + aOutputData.LowerCase(); + } + else + { + ExtractQueryL(aInputData, *aQuery, aOutputData); + aOutputData.LowerCase(); + } } // ---------------------------------------------------------------------------- @@ -403,81 +423,63 @@ // Subset search function. Refer the above function for more description. // ---------------------------------------------------------------------------- void CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, - RPointerArray& aSearchSet, - RPointerArray& aSearchQuery, + RPointerArray& searchSet, + RPointerArray& searchQuery, TUint8 aFilteredDataMatch, - TBool aIsSearchInGroup, - const RArray& aContactsInGroup) + TBool isSearchInGroup, + RArray& aContactsInGroup, + TInt keyboardMode) { PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") ); - //__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") ); - - TInt maxcount = 0; - // Convert the individual queries to string form RPointerArray mySearchQuery; - CleanupResetAndDestroyPushL( mySearchQuery ); // Remember a temporary copy of query list // Copy the content of searchQuery - const TInt searchQueryCount = aSearchQuery.Count(); - for (TInt i=0; i < searchQueryCount; i++) + for (TInt i=0; iFindUtilECE()->GetPartOfQueryL( - *(aSearchQuery[i]), 0, aSearchQuery[i]->Count()-1, *tempQuery ); - mySearchQuery.AppendL(tempQuery); - CleanupStack::Pop(tempQuery); // ownership transferred + iAlgorithm->FindUtilECE()->GetPartOfQueryL(*(searchQuery[i]), 0, + searchQuery[i]->Count()-1, *tempQuery); + mySearchQuery.Append(tempQuery); } // Sort the query items according to the length of each query - TLinearOrder rule(CPcsAlgorithm2Utils::CompareLength); + TLinearOrder rule(Compare4); mySearchQuery.Sort(rule); // To hold the match results RPointerArray tmpMatchSet; - CleanupResetAndDestroyPushL( tmpMatchSet ); - // Parse thru each search set elements and filter the results - const TInt searchSetCount = aSearchSet.Count(); - for (TInt index = 0; index < searchSetCount; index++) + // Parse thru each search set elements and filter the results + for (int index = 0; index < searchSet.Count(); index++) { - CPcsPoolElement* poolElement = static_cast (aSearchSet[index]); + CPcsPoolElement* poolElement = static_cast (searchSet[index]); CPsData* psData = poolElement->GetPsData(); psData->ClearDataMatches(); - // Skip the contact if we are doing a group search and contact doesn't belong to the group - if ( aIsSearchInGroup && - aContactsInGroup.Find( psData->Id() ) == KErrNotFound ) - { - continue; - } - TBool isMatch = ETrue; - TInt wordMatches = 0; + TUint8 wordMatches = 0; // Reset iWordMatches to zero ClearWordMatches(); // Check for each query atleast one data element matches // Loop from the last query so that longest match is seen first - for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--) + for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--) { TBool queryMatch = EFalse; CPsQuery* tmpPsQuery = mySearchQuery[queryIndex]; - const TInt dataElementCount = psData->DataElementCount(); - for (TInt dataIndex = 0; dataIndex < dataElementCount; dataIndex++) + for (TInt dataIndex = 0; dataIndex < psData->DataElementCount(); dataIndex++) { // Filter off data fields not required in search - TUint8 bitIndex = 1 << dataIndex; - TUint8 filter = bitIndex & aFilteredDataMatch; - - // Omit the data fields which is not required in search - // or not matched with the pool element - if ( filter == 0x0 ) + TReal bitIndex; + Math::Pow(bitIndex, 2, dataIndex); + + TUint8 filter = (TUint8) bitIndex & aFilteredDataMatch; + if (filter == 0x0) { // Move to next data continue; @@ -495,9 +497,27 @@ { wordIndex++; + TPtrC queryPtr = tmpPsQuery->QueryAsStringLC(); + TBool matched = EFalse; + + if (keyboardMode == EModeUndefined) + { + matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery); + } + else if (keyboardMode == EItut) + { + matched = iAlgorithm->FindUtil()->Interface()-> + MatchRefineL(tmpData, queryPtr, ECustomConverter, iAlgorithm); + } + else // Qwerty + { + matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(tmpData, queryPtr); + + } + + CleanupStack::PopAndDestroy(); // queryPtr + // Compare the data against query - TBool matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery); - if (matched) { psData->SetDataMatch(dataIndex); @@ -520,18 +540,25 @@ // Extract matched character sequence and fill in temp array TInt len = tmpPsQuery->Count(); - if (iAlgorithm->FindUtilECE()->IsChineseWordIncluded(tmpData)) + if (iAlgorithm->FindUtilECE()->IsChineseWord(tmpData)) { len = 1; } - TPtrC seq = tmpData.Left(len); - CPcsAlgorithm2Utils::AppendMatchToSeqL( tmpMatchSet, seq ); - - // TODO: Match seqs could be extracted from actual - // match locations by using the other overload of - // CFindUtilChineseECE::MatchRefineL(). - // Currently, match seq data is not used by clients. + HBufC* seq = HBufC::NewL(len); + *seq = tmpData.Mid(0, len); + + seq->Des().UpperCase(); + TIdentityRelation searchRule(Compare3); + if (tmpMatchSet.Find(seq, searchRule) == KErrNotFound) + { + tmpMatchSet.Append(seq); + } + else + { + delete seq; + seq = NULL; + } } } @@ -547,50 +574,112 @@ break; } } - // If match add the element to the result set // And before adding to the result set, check if there is atleast one match per query - if ( isMatch && wordMatches >= mySearchQuery.Count() ) + if ((isMatch) && (wordMatches >= mySearchQuery.Count())) { - aAlgorithmFilterHelper->AddL(psData, tmpMatchSet); - maxcount++; + if (isSearchInGroup) + { + if (aContactsInGroup.Find(psData->Id()) != KErrNotFound) + { + aAlgorithmFilterHelper->AddL(psData, tmpMatchSet); + } + } + else + { + aAlgorithmFilterHelper->AddL(psData, tmpMatchSet); + } } - - if ( iMaxCount != -1 && maxcount > iMaxCount ) - { - break; - } - + // Cleanup the match sequence array as // they are stored in pattern details structure tmpMatchSet.ResetAndDestroy(); } - CleanupStack::PopAndDestroy( &tmpMatchSet ); // ResetAndDestroy - CleanupStack::PopAndDestroy( &mySearchQuery ); // ResetAndDestroy - - //__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") ); + mySearchQuery.Reset(); PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") ); } // ---------------------------------------------------------------------------- -// CPcsAlgorithm2MultiSearchHelper::SetWordMap +// CPcsAlgorithm2MultiSearchHelper::SetWordMap() // ---------------------------------------------------------------------------- void CPcsAlgorithm2MultiSearchHelper::SetWordMap(TInt aIndex, TInt aPosition) { - TUint8 val = 1 << aPosition; - iWordMatches[aIndex] |= val; + TReal val; + Math::Pow(val, 2, aPosition); + + iWordMatches[aIndex] |= (TUint8) val; + } + +// ---------------------------------------------------------------------------- +// CPcsAlgorithm2MultiSearchHelper::IsWordMatch() +// ---------------------------------------------------------------------------- +TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex) + { + TReal val; + Math::Pow(val, 2, aWordIndex); + + return (iWordMatches[aDataIndex] & (TUint8) val); } // ---------------------------------------------------------------------------- -// CPcsAlgorithm2MultiSearchHelper::IsWordMatch +// CPcsAlgorithm2MultiSearchHelper::ExtractQueryL() +// Extracts the query as a string. If the mode of query item is ITU numeric +// character is used. Else the character is used. +// ---------------------------------------------------------------------------- +void CPcsAlgorithm2MultiSearchHelper::ExtractQueryL(CPsQuery& aQuery, TDes& aOutput) + { + for (int i = 0; i < aQuery.Count(); i++) + { + if (aQuery.GetItemAtL(i).Mode() == EItut) + { + TBuf outBuf; + keyMap->GetNumericKeyString(aQuery.QueryAsStringLC(), outBuf); + aOutput.Append(outBuf[i]); + CleanupStack::PopAndDestroy(); + } + else + { + aOutput.Append(aQuery.GetItemAtL(i).Character()); + } + } + } + +// ---------------------------------------------------------------------------- +// CPcsAlgorithm2MultiSearchHelper::ExtractQueryL() +// Converts the input data refering the modes in the query. +// If the mode of query item is ITU numeric character is used. Else the character +// is used. // ---------------------------------------------------------------------------- -TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex) +void CPcsAlgorithm2MultiSearchHelper::ExtractQueryL(TDesC& aInput, CPsQuery& aQuery, TDes& aOutput) { - TUint8 val = 1 << aWordIndex; - return (iWordMatches[aDataIndex] & val); + TInt len = -1; + + // Always loop thru the lowest length + if (aInput.Length() > aQuery.Count()) + { + len = aQuery.Count(); + } + else + { + len = aInput.Length(); + } + + for (int i = 0; i < len; i++) + { + if (aQuery.GetItemAtL(i).Mode() == EItut) + { + TBuf outBuf; + keyMap->GetNumericKeyString(aInput, outBuf); + aOutput.Append(outBuf[i]); + } + else + { + aOutput.Append(aInput[i]); + } + } } // ---------------------------------------------------------------------------- @@ -610,7 +699,7 @@ } // ---------------------------------------------------------------------------- -// CPcsAlgorithm2MultiSearchHelper::ClearWordMatches +// CPcsAlgorithm2MultiSearchHelper::BitsSet32 // Function to reset the iWordMatches // ---------------------------------------------------------------------------- void CPcsAlgorithm2MultiSearchHelper::ClearWordMatches() @@ -640,14 +729,13 @@ { // Scan the end of the word TInt end = beg; - while ( end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace() ) + for (; end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace(); ++end) { - end++; } // Create a new query object and append CPsQuery* newQuery = CPsQuery::NewL(); - for (TInt i = beg; i < end; i++) + for (int i = beg; i < end; i++) { CPsQueryItem* item = CPsQueryItem::NewL(); item->SetCharacter(aQuery.GetItemAtL(i).Character()); @@ -664,6 +752,35 @@ return query; } +// ---------------------------------------------------------------------------- +// CPcsAlgorithm2MultiSearchHelper::FilterDataFieldsL() +// Constructs a bit pattern using the required/supported data fields +// For example, 6, 4 and 27 are supported fields <-- 00000111 +// 6 and 4 are required fields <-- 00000011 +// Bit pattern returned is 00000011. +// ---------------------------------------------------------------------------- +TUint8 CPcsAlgorithm2MultiSearchHelper::FilterDataFieldsL(RArray& aRequiredDataFields, + RArray& aSupportedDataFields) + { + TUint8 filteredMatch = 0x0; + + for (int i = 0; i < aSupportedDataFields.Count(); i++) + { + for (int j = 0; j < aRequiredDataFields.Count(); j++) + { + if (aSupportedDataFields[i] == aRequiredDataFields[j]) + { + TReal val; + Math::Pow(val, 2, i); + + filteredMatch |= (TUint8) val; + } + } + } + + return filteredMatch; + } + // End of file