predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2MultiSearchHelper.cpp
branchRCL_3
changeset 85 38bb213f60ba
parent 74 6b5524b4f673
equal deleted inserted replaced
74:6b5524b4f673 85:38bb213f60ba
    21 #include "CPcsAlgorithm2Utils.h"
    21 #include "CPcsAlgorithm2Utils.h"
    22 #include "CPcsDefs.h"
    22 #include "CPcsDefs.h"
    23 #include <collate.h>
    23 #include <collate.h>
    24 #include <biditext.h>
    24 #include <biditext.h>
    25 
    25 
    26 
    26 // Compare functions
       
    27 TBool Compare2(const HBufC& aFirst, const HBufC& aSecond)
       
    28     {
       
    29     TPtrC t1(aFirst);
       
    30     TPtrC t2(aSecond);
       
    31     return (t1.Length() > t2.Length());
       
    32     }
       
    33 
       
    34 TBool Compare3(const TDesC& aFirst, const TDesC& aSecond)
       
    35     {
       
    36     return aFirst == aSecond;
       
    37     }
       
    38 
       
    39 TBool Compare4(const CPsQuery& aFirst, const CPsQuery& aSecond)
       
    40     {
       
    41     CPsQuery& first = const_cast<CPsQuery&> (aFirst);
       
    42     CPsQuery& second = const_cast<CPsQuery&> (aSecond);
       
    43     
       
    44     return (first.Count() > second.Count());
       
    45     }
    27 // ============================== MEMBER FUNCTIONS ============================
    46 // ============================== MEMBER FUNCTIONS ============================
    28 
    47 
    29 // ----------------------------------------------------------------------------
    48 // ----------------------------------------------------------------------------
    30 // CPcsAlgorithm2MultiSearchHelper::NewL
    49 // CPcsAlgorithm2MultiSearchHelper::NewL
    31 // Two Phase Construction
    50 // Two Phase Construction
    61 void CPcsAlgorithm2MultiSearchHelper::ConstructL(CPcsAlgorithm2* aAlgorithm)
    80 void CPcsAlgorithm2MultiSearchHelper::ConstructL(CPcsAlgorithm2* aAlgorithm)
    62     {
    81     {
    63     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::ConstructL") );
    82     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::ConstructL") );
    64 
    83 
    65     iAlgorithm = aAlgorithm;
    84     iAlgorithm = aAlgorithm;
    66     iKeyMap = iAlgorithm->GetKeyMap();
    85     keyMap = iAlgorithm->GetKeyMap();
    67     iMaxCount = 0;
    86 
    68     
       
    69     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::ConstructL") );
    87     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::ConstructL") );
    70     }
    88     }
    71 
    89 
    72 // ----------------------------------------------------------------------------
    90 // ----------------------------------------------------------------------------
    73 // CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper
    91 // CPcsAlgorithm2MultiSearchHelper::CPcsAlgorithm2MultiSearchHelper
    74 // Destructor
    92 // Destructor
    75 // ----------------------------------------------------------------------------
    93 // ----------------------------------------------------------------------------
    76 CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper()
    94 CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper()
    77     {
    95     {
    78     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper") );
    96     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper") );
    96 //     data element has not matched for multiple queries.
   114 //     data element has not matched for multiple queries.
    97 // (9) Now include the element in the result.
   115 // (9) Now include the element in the result.
    98 // ----------------------------------------------------------------------------
   116 // ----------------------------------------------------------------------------
    99 void CPcsAlgorithm2MultiSearchHelper::SearchMultiL(const CPsSettings& aSettings, 
   117 void CPcsAlgorithm2MultiSearchHelper::SearchMultiL(const CPsSettings& aSettings, 
   100                                                    RPointerArray<CPsQuery>& aPsQuery,
   118                                                    RPointerArray<CPsQuery>& aPsQuery,
   101                                                    TBool aIsSearchInGroup, 
   119                                                    TBool isSearchInGroup, 
   102                                                    const RArray<TInt>& aContactsInGroup, 
   120                                                    RArray<TInt>& aContactsInGroup, 
   103                                                    RPointerArray<CPsData>& aSearchResults,
   121                                                    RPointerArray<CPsData>& searchResults,
   104                                                    RPointerArray<CPsPattern>& aSearchSeqs)
   122                                                    RPointerArray<CPsPattern>& searchSeqs,
   105     {
   123                                                    TInt keyboardMode)
       
   124     {
       
   125     __LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   106     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   126     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   107 
   127 
   108     //__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
       
   109 
       
   110     PRINTQUERYLIST ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL: "), aPsQuery );
       
   111 
       
   112     iMaxCount = aSettings.MaxResults();
       
   113     // Create CPcsAlgorithm2FilterHelper object to be used for filtering the results
   128     // Create CPcsAlgorithm2FilterHelper object to be used for filtering the results
   114     TSortType sortType = aSettings.GetSortType();
   129     TSortType sortType = aSettings.GetSortType();
   115     CPcsAlgorithm2FilterHelper* filterHelper = CPcsAlgorithm2FilterHelper::NewL(sortType);
   130     CPcsAlgorithm2FilterHelper* filterHelper = CPcsAlgorithm2FilterHelper::NewL(sortType);
   116     CleanupStack::PushL( filterHelper );
       
   117     RPointerArray<CPcsPoolElement> elements;
   131     RPointerArray<CPcsPoolElement> elements;
   118     CleanupClosePushL( elements );
       
   119 
   132 
   120     iMultiSearchResultsArr.ResetAndDestroy();
   133     iMultiSearchResultsArr.ResetAndDestroy();
   121 
   134 
   122     // Get the data stores  
   135     // Get the data stores  
   123     RPointerArray<TDesC> dataStores;
   136     RPointerArray<TDesC> aDataStores;
   124     CleanupResetAndDestroyPushL( dataStores );
   137     aSettings.SearchUrisL(aDataStores);
   125     aSettings.SearchUrisL(dataStores);
       
   126 
   138 
   127     // Get the required display fields from the client
   139     // Get the required display fields from the client
   128     RArray<TInt> requiredDataFields;
   140     RArray<TInt> requiredDataFields;
   129     CleanupClosePushL( requiredDataFields );
       
   130     aSettings.DisplayFieldsL(requiredDataFields);
   141     aSettings.DisplayFieldsL(requiredDataFields);
   131 
   142 
   132     // Search from cache based on first character of 1st item in query list
   143     // Search from cache based on first character
   133     const CPsQueryItem& firstCharItem = aPsQuery[0]->GetItemAtL(0);
   144     const CPsQueryItem& firstCharItem = aPsQuery[0]->GetItemAtL(0);
   134     TInt cachePoolId = iKeyMap->PoolIdForCharacter( firstCharItem.Character(), firstCharItem.Mode() );
   145     TInt numValue  = keyMap->PoolIdForCharacter( firstCharItem.Character() );
   135 
   146     
   136     // Get the elements from all the databases
   147     // Get the elements from all the databases
   137     const TInt dataStoresCount = dataStores.Count(); 
   148     for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
   138     for (TInt dsIndex = 0; dsIndex < dataStoresCount; dsIndex++)
       
   139         {
   149         {
   140         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
   150         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
   141         iMultiSearchResultsArr.Append(temp);
   151         iMultiSearchResultsArr.Append(temp);
   142 
   152 
   143         // Get the contents for this data store
   153         // Get the contents for this data store
   144         TInt arrayIndex = iAlgorithm->GetCacheIndex(*(dataStores[dsIndex]));
   154         TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
   145         if (arrayIndex < 0)
   155         if (arrayIndex < 0)
   146             {
   156             {
   147             continue;
   157             continue;
   148             }
   158             }
   149         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
   159         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
   150         cache->GetContactsForKeyL(cachePoolId, elements);
   160         cache->GetContactsForKeyL(numValue, elements);
   151 
   161 
   152         // Get the supported data fields for this data store
   162         // Get the supported data fields for this data store
   153         RArray<TInt> supportedDataFields;
   163         RArray<TInt> supportedDataFields;
   154         CleanupClosePushL( supportedDataFields );
       
   155         cache->GetDataFields(supportedDataFields);
   164         cache->GetDataFields(supportedDataFields);
   156 
   165 
   157         // Get the filtered data fields for this data store
   166         // Get the filtered data fields for this data store    		
   158         TUint8 filteredDataMatch = CPcsAlgorithm2Utils::FilterDataFieldsL(
   167         TUint8 filteredDataMatch = FilterDataFieldsL(requiredDataFields, supportedDataFields);
   159                 requiredDataFields, supportedDataFields);
       
   160 
   168 
   161         // Filter the results now
   169         // Filter the results now
   162         FilterResultsMultiL(filterHelper, 
   170         FilterResultsMultiL(filterHelper, elements, aPsQuery, filteredDataMatch, 
   163                             elements, 
   171                             isSearchInGroup, aContactsInGroup, keyboardMode);
   164                             aPsQuery, 
   172 
   165                             filteredDataMatch, 
   173         // If alphabetical sorting, get the results for this datastore               
   166                             aIsSearchInGroup, 
       
   167                             aContactsInGroup);
       
   168 
       
   169         // If alphabetical sorting, get the results for this datastore
       
   170         if (sortType == EAlphabetical)
   174         if (sortType == EAlphabetical)
   171             {
   175             {
   172             filterHelper->GetResults(*(iMultiSearchResultsArr[dsIndex]));
   176             filterHelper->GetResults(*(iMultiSearchResultsArr[dsIndex]));
   173             }
   177             }
   174 
   178 
   175         elements.Reset();
   179         elements.Reset();
   176         CleanupStack::PopAndDestroy( &supportedDataFields ); // Close
   180         supportedDataFields.Reset();
   177         }
   181         }
   178     CleanupStack::PopAndDestroy( &requiredDataFields ); // Close
   182     aDataStores.ResetAndDestroy();
   179     CleanupStack::PopAndDestroy( &dataStores );         // ResetAndDestroy
   183     requiredDataFields.Reset();
   180 
   184 
   181     // If alphabetical sorting, merge the result sets of all datastores
   185     // If alphabetical sorting, merge the result sets of all datastores
   182     if (sortType == EAlphabetical)
   186     if (sortType == EAlphabetical)
   183         {
   187         {
   184         // Form the complete searchResults array
   188         // Form the complete searchResults array
   185         CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr, 
   189         CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr, searchResults);
   186                                                         aSearchResults);
       
   187         }
   190         }
   188     else
   191     else
   189         {
   192         {
   190         // Results are already sorted patternbased
   193         // Results are already sorted patternbased
   191         filterHelper->GetResults(aSearchResults);
   194         filterHelper->GetResults(searchResults);
   192         }
   195         }
   193 
   196 
   194     // Get the sorted match sequence list
   197     // Get the sorted match sequence list
   195     filterHelper->GetPatternsL(aSearchSeqs);
   198     filterHelper->GetPatternsL(searchSeqs);
   196 
   199 
   197     PRINT1 ( _L("Number of search results = %d"), aSearchResults.Count() );
   200     PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
   198 
   201 
   199     // Cleanup
   202     // Cleanup             
   200     for (TInt i = 0; i < iMultiSearchResultsArr.Count(); i++)
   203     for (TInt i = 0; i < iMultiSearchResultsArr.Count(); i++)
   201         {
   204         {
   202         iMultiSearchResultsArr[i]->Reset();
   205         iMultiSearchResultsArr[i]->Reset();
   203         delete iMultiSearchResultsArr[i];
   206         delete iMultiSearchResultsArr[i];
   204         iMultiSearchResultsArr[i] = NULL;
   207         iMultiSearchResultsArr[i] = NULL;
   205         }
   208         }
   206 
   209 
   207     iMultiSearchResultsArr.Reset();
   210     iMultiSearchResultsArr.Reset();
   208     CleanupStack::PopAndDestroy( &elements ); // Close
   211     delete filterHelper;
   209     CleanupStack::PopAndDestroy( filterHelper );
       
   210 
       
   211     //__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
       
   212 
   212 
   213     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   213     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   214     }
   214     __LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
   215 
   215     }
   216 // ----------------------------------------------------------------------------
   216 
   217 // CPcsAlgorithm1MultiSearchHelper::SearchMatchSeqMultiL
   217 // ----------------------------------------------------------------------------
   218 // Function adds matches, and locations based on multi query, and data
   218 // CPcsAlgorithm2MultiSearchHelper::SearchInputMultiL
   219 // Duplicate locations are allowed (as they are removed later anyway)
   219 // Function to search match sequences for multi query
   220 // Post condition locations in index order
   220 // ----------------------------------------------------------------------------
   221 // ----------------------------------------------------------------------------
   221 void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL(RPointerArray<CPsQuery>& aPsQuery, 
   222 void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL( RPointerArray<CPsQuery>& aPsQuery,
   222                                                            TDesC& aData, 
   223                                                             const TDesC& aData,
   223                                                            RPointerArray<TDesC>& aMatchSet,
   224                                                             RPointerArray<TDesC>& aMatchSeq,
   224                                                            RArray<TPsMatchLocation>& aMatchLocation)
   225                                                             RArray<TPsMatchLocation>& aMatchLocation )
       
   226     {
   225     {
   227     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
   226     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
   228 
   227     CleanupResetAndDestroyPushL( aMatchSet );
   229     TLex lex(aData);
   228     CleanupClosePushL( aMatchLocation );
   230     while ( !lex.Eos() ) // Search thru all words
   229     
   231         {
   230     RPointerArray<HBufC> queryList;
   232         TPtrC currentWord = lex.NextToken(); // next word
   231     ConvertQueryToListL(aPsQuery, queryList);
   233 
   232 
   234         const TInt psQueryCount = aPsQuery.Count(); 
   233     RPointerArray<HBufC> tempqueryList;
   235         for ( TInt queryIndex = 0; queryIndex < psQueryCount; ++queryIndex )
   234     // Remember a temporary copy of query list
   236             {
   235     // since we sort the queries
   237             CPsQuery* currentQuery = aPsQuery[queryIndex];
   236     for (TInt i = 0; i < queryList.Count(); i++)
   238 
   237         {
   239             RArray<TInt> matchPos;
   238         tempqueryList.Append(queryList[i]);
   240             CleanupClosePushL( matchPos );
   239         }
   241             RArray<TInt> matchLen;
   240     // To hold the match results
   242             CleanupClosePushL( matchLen );
   241     RPointerArray<TDesC> tmpMatchSet;
   243             
   242     TBool isMatch = ETrue;
   244             if ( iAlgorithm->FindUtilECE()->MatchRefineL( currentWord, *currentQuery, matchPos, matchLen, ETrue ) )
   243     TUint32 wordMatches = 0;
   245                 {
   244 
   246                 // Some matches found. Add all of them to result array.
   245     // Sort the query items before we search them
   247                 ASSERT( matchPos.Count() == matchLen.Count() );
   246     TLinearOrder<HBufC> rule(Compare2);
   248                 
   247     queryList.Sort(rule);
   249                 TInt wordStartPos = lex.Offset() - currentWord.Length();
   248 
   250                 const TInt matchPosCount =  matchPos.Count(); 
   249     // Check for each query atleast one data element matches
   251                 for ( TInt i = 0 ; i < matchPosCount; ++i )
   250     // Loop from the last query so that longest match is seen first
       
   251     for (TInt queryIndex = queryList.Count() - 1; queryIndex >= 0; queryIndex--)
       
   252         {
       
   253         TBool queryMatch = EFalse;
       
   254         HBufC* tmpQuery = queryList[queryIndex];
       
   255         // Get the original query mode corresponding to this query
       
   256         TInt modeIndex = tempqueryList.Find(tmpQuery);
       
   257 
       
   258         TLex lex(aData);
       
   259 
       
   260         // First word
       
   261         TPtrC tmpData = lex.NextToken();
       
   262 
       
   263         TInt beg = lex.Offset() - tmpData.Length(); // start index of match sequence
       
   264 
       
   265         TInt wordIndex = -1;
       
   266         // Search thru multiple words
       
   267         while ((tmpData.Length() != 0) && (!queryMatch))
       
   268             {
       
   269             wordIndex++;
       
   270 
       
   271             TPtr ptr = tmpQuery->Des();
       
   272 
       
   273             // Perform two checks.
       
   274             // 1. Ensure that the word is not matched against any previous query
       
   275             // 2. If it is the first match to the query
       
   276             TBool isWordMatch = EFalse;
       
   277             TReal val;
       
   278             Math::Pow(val, 2, wordIndex);
       
   279             isWordMatch = wordMatches & (TUint) val;
       
   280 
       
   281             if (!isWordMatch)
       
   282                 {
       
   283                 // Check if no word is matched till now for this query
       
   284                 if (!queryMatch)
   252                     {
   285                     {
   253                     TPsMatchLocation newLocation = { wordStartPos + matchPos[i], matchLen[i], 
   286                     queryMatch = ETrue;
   254                             TBidiText::TextDirectionality(currentWord) };
   287                     //set the word match bit
   255                     aMatchLocation.AppendL( newLocation );
   288                     TReal val;
   256 
   289                     Math::Pow(val, 2, wordIndex);
   257                     TPtrC matchPart = currentWord.Mid( matchPos[i], matchLen[i] );
   290                     wordMatches |= (TUint) val;
   258                     CPcsAlgorithm2Utils::AppendMatchToSeqL( aMatchSeq, matchPart );
       
   259                     }
   291                     }
   260                 }
   292 
   261                 
   293                 TPsMatchLocation tempLocation;
   262             CleanupStack::PopAndDestroy( &matchLen );
   294                 // check for directionality of the text
   263             CleanupStack::PopAndDestroy( &matchPos );
   295                 TBool found(EFalse);
   264             }
   296                 TBidiText::TDirectionality dir = TBidiText::TextDirectionality(tmpData, &found);
   265         }
   297 
       
   298                 tempLocation.index = beg;
       
   299                 tempLocation.length = 0;
       
   300                 tempLocation.direction = dir;
       
   301 
       
   302                 // Add the match location to the data structure array
       
   303                 aMatchLocation.Append(tempLocation);
       
   304                 }
       
   305             }
       
   306         // Next word
       
   307         tmpData.Set(lex.NextToken());
       
   308         beg = lex.Offset() - tmpData.Length(); // start index of next word  
       
   309 
       
   310 
       
   311         // No data element matches the query. Ignore this result.
       
   312         if (queryMatch == EFalse)
       
   313             {
       
   314             isMatch = EFalse;
       
   315             break;
       
   316             }
       
   317         }
       
   318 
       
   319     // Count the number of bits set
       
   320     TInt matchCount = 0;
       
   321     matchCount = BitsSet32(wordMatches);
       
   322 
       
   323     // If match add the element to the result set
       
   324     // Before adding to the result set, check if there is atleast one match per query
       
   325     // Number of bits set in word matches is atleast equal to total number of queries.
       
   326     if ((isMatch) && (matchCount >= queryList.Count()))
       
   327         {
       
   328 
       
   329         // Include the match sequences in the final results
       
   330         for (int i = 0; i < tmpMatchSet.Count(); i++)
       
   331             {
       
   332             TIdentityRelation<TDesC> rule(Compare3);
       
   333             CleanupStack::PushL(tmpMatchSet[i]);
       
   334             if (aMatchSet.Find(tmpMatchSet[i], rule) == KErrNotFound)
       
   335                 {
       
   336                 aMatchSet.Append(tmpMatchSet[i]);
       
   337                 CleanupStack::Pop();
       
   338                 }
       
   339             else
       
   340                 {
       
   341                 CleanupStack::PopAndDestroy();
       
   342                 }
       
   343             }
       
   344 
       
   345         // Reset tmp match set
       
   346         tmpMatchSet.Reset();
       
   347         }
       
   348     else
       
   349         {
       
   350         tmpMatchSet.ResetAndDestroy();
       
   351         }
       
   352 
       
   353     // Free the query list
       
   354     queryList.ResetAndDestroy();
       
   355     tempqueryList.Reset();
       
   356     
       
   357     CleanupStack::Pop();
       
   358     CleanupStack::Pop( &aMatchSet );
   266 
   359 
   267     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
   360     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
   268     }
   361     }
   269 
   362 
   270 // ----------------------------------------------------------------------------
   363 // ----------------------------------------------------------------------------
   271 // CPcsAlgorithm2MultiSearchHelper::LookupMatchL
   364 // CPcsAlgorithm2MultiSearchHelper::ConvertQueryToList
   272 // ----------------------------------------------------------------------------
   365 // Converts the multiple search queries to a list
   273 void CPcsAlgorithm2MultiSearchHelper::LookupMatchL( CPsQuery& aSearchQuery,
   366 // ----------------------------------------------------------------------------
   274     const TDesC& aData, TDes& aMatchedData )
   367 void CPcsAlgorithm2MultiSearchHelper::ConvertQueryToListL(RPointerArray<CPsQuery>& aSearchQuery, 
   275     {
   368                                                           RPointerArray<HBufC>& aQueryList)
   276     _LIT( KSpace, " " );
   369     {
   277     aMatchedData.Zero();
   370     for (int queryIndex = 0; queryIndex < aSearchQuery.Count(); queryIndex++)
   278     RPointerArray<CPsQuery> queryList = MultiQueryL( aSearchQuery );
   371         {
   279     CleanupResetAndDestroyPushL( queryList );
   372         CPsQuery* query = aSearchQuery[queryIndex];
       
   373 
       
   374         HBufC* tmpSearchQuery = HBufC::NewL(KPsQueryMaxLen);
       
   375         TPtr ptr = tmpSearchQuery->Des();
       
   376 
       
   377         if (query->KeyboardModeL() == EItut) // ITU
       
   378             {
       
   379             keyMap->GetNumericKeyString(query->QueryAsStringLC(), ptr);
       
   380             CleanupStack::PopAndDestroy();
       
   381             }
       
   382         else if (query->KeyboardModeL() == EQwerty) // QWERTY
       
   383             {
       
   384             ptr = query->QueryAsStringLC();
       
   385             ptr.LowerCase();
       
   386             CleanupStack::PopAndDestroy();
       
   387             }
       
   388         else // UNDEFINED
       
   389             {
       
   390             ExtractQueryL(*query, ptr);
       
   391             ptr.LowerCase();
       
   392             }
       
   393         aQueryList.Append(tmpSearchQuery);
       
   394         }
       
   395     }
       
   396 
       
   397 // ----------------------------------------------------------------------------
       
   398 // CPcsAlgorithm2MultiSearchHelper::ConvertdDataToKeyBoardModeL
       
   399 // Converts the input data to the key board mode specified by the query
       
   400 // ----------------------------------------------------------------------------
       
   401 void CPcsAlgorithm2MultiSearchHelper::ConvertdDataToKeyBoardModeL(CPsQuery* aQuery, 
       
   402                                                                   TPtrC aInputData, 
       
   403                                                                   TBuf<KPsQueryMaxLen>& aOutputData)
       
   404     {
       
   405     if (aQuery->KeyboardModeL() == EItut)
       
   406         {
       
   407         keyMap->GetNumericKeyString(aInputData, aOutputData);
       
   408         }
       
   409     else if (aQuery->KeyboardModeL() == EQwerty)
       
   410         {
       
   411         aOutputData = aInputData;
       
   412         aOutputData.LowerCase();
       
   413         }
       
   414     else
       
   415         {
       
   416         ExtractQueryL(aInputData, *aQuery, aOutputData);
       
   417         aOutputData.LowerCase();
       
   418         }
       
   419     }
       
   420 
       
   421 // ----------------------------------------------------------------------------
       
   422 // CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL
       
   423 // Subset search function. Refer the above function for more description.
       
   424 // ----------------------------------------------------------------------------
       
   425 void CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, 
       
   426                                                           RPointerArray<CPcsPoolElement>& searchSet,
       
   427                                                           RPointerArray<CPsQuery>& searchQuery, 
       
   428                                                           TUint8 aFilteredDataMatch,
       
   429                                                           TBool isSearchInGroup, 
       
   430                                                           RArray<TInt>& aContactsInGroup,
       
   431                                                           TInt keyboardMode)
       
   432     {
       
   433     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
       
   434 
   280     // Convert the individual queries to string form
   435     // Convert the individual queries to string form
   281     RPointerArray<CPsQuery> mySearchQuery;
   436     RPointerArray<CPsQuery> mySearchQuery;
   282     CleanupResetAndDestroyPushL( mySearchQuery );
       
   283 
   437 
   284     // Remember a temporary copy of query list
   438     // Remember a temporary copy of query list
   285     // Copy the content of searchQuery
   439     // Copy the content of searchQuery
   286     const TInt searchQueryCount = queryList.Count();
   440     for (TInt i=0; i<searchQuery.Count(); i++)
   287     for (TInt i = 0; i < searchQueryCount; i++ )
       
   288         {
   441         {
   289         CPsQuery* tempQuery = CPsQuery::NewL();
   442         CPsQuery* tempQuery = CPsQuery::NewL();
   290         CleanupStack::PushL( tempQuery );
   443         iAlgorithm->FindUtilECE()->GetPartOfQueryL(*(searchQuery[i]), 0, 
   291         iAlgorithm->FindUtilECE()->GetPartOfQueryL( *(queryList[i]), 0,
   444                                                    searchQuery[i]->Count()-1, *tempQuery);
   292             queryList[i]->Count() - 1, *tempQuery );
   445         mySearchQuery.Append(tempQuery);
   293         mySearchQuery.AppendL( tempQuery );
       
   294         CleanupStack::Pop( tempQuery ); // ownership transferred
       
   295         }
   446         }
   296 
   447 
   297     // Sort the query items according to the length of each query 
   448     // Sort the query items according to the length of each query 
   298     TLinearOrder<CPsQuery> rule( CPcsAlgorithm2Utils::CompareLength );
   449     TLinearOrder<CPsQuery> rule(Compare4);
   299     mySearchQuery.Sort( rule );
   450     mySearchQuery.Sort(rule);
   300 
   451 
   301     // To hold the match results
   452     // To hold the match results
   302     RPointerArray<TDesC> tmpMatchSet;
   453     RPointerArray<TDesC> tmpMatchSet;
   303     CleanupResetAndDestroyPushL( tmpMatchSet );
   454 
   304 
   455     // Parse thru each search set elements and filter the results    
   305     TBool isMatch = ETrue;
   456     for (int index = 0; index < searchSet.Count(); index++)
   306     TInt wordMatches = 0;
   457         {
   307 
   458         CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
   308     // Reset iWordMatches to zero 
       
   309     ClearWordMatches();
       
   310 
       
   311     // Check for each query atleast one data element matches
       
   312     // Loop from the last query so that longest match is seen first
       
   313     for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex-- )
       
   314         {
       
   315         TBool queryMatch = EFalse;
       
   316         CPsQuery* tmpPsQuery = mySearchQuery[queryIndex];
       
   317 
       
   318         TInt wordIndex = -1;
       
   319         TLex lex( aData );
       
   320 
       
   321         // First word
       
   322         TPtrC tmpData = lex.NextToken();
       
   323 
       
   324         // Search thru multiple words
       
   325         while (tmpData.Length() != 0 )
       
   326             {
       
   327             wordIndex++;
       
   328 
       
   329             // Compare the data against query
       
   330             TBool matched = iAlgorithm->FindUtilECE()->MatchRefineL( tmpData,
       
   331                 *tmpPsQuery );
       
   332 
       
   333             if ( matched )
       
   334                 {
       
   335                 // Perform two checks.
       
   336                 // 1. Ensure that the word is not matched against any previous query
       
   337                 // 2. If it is the first match to the query
       
   338                 TBool isWordMatch = IsWordMatch( 0, wordIndex );
       
   339 
       
   340                 // Check if the current word is not matched to any query
       
   341                 // For example, there is a contact named "abc a" and query is key2
       
   342                 // The key2 could match the first and second 'a'. So it is required to 
       
   343                 // check if the current word has aready been matched before.
       
   344 
       
   345                 if ( !isWordMatch )
       
   346                     {
       
   347                     // Check if no word is matched for this query till now
       
   348                     if ( !queryMatch )
       
   349                         {
       
   350                         wordMatches++;
       
   351                         queryMatch = ETrue;
       
   352                         SetWordMap( 0, wordIndex );
       
   353                         // Extract matched character sequence and fill in temp array
       
   354                         TInt len = tmpPsQuery->Count();
       
   355                         if ( iAlgorithm->FindUtilECE()->IsChineseWordIncluded(
       
   356                             tmpData ) )
       
   357                             {
       
   358                             // A Chinese word could be matched by serveral keys
       
   359                             // It is hard to know the matched query length. So set it to 1
       
   360                             // as a trick result
       
   361                             len = 1;
       
   362                             }
       
   363 
       
   364                         TPtrC seq = tmpData.Left( len );
       
   365                         CPcsAlgorithm2Utils::AppendMatchToSeqL( tmpMatchSet,
       
   366                             seq );
       
   367                         }
       
   368                     }
       
   369                 }
       
   370 
       
   371             // Next word
       
   372             tmpData.Set( lex.NextToken() );
       
   373             }
       
   374 
       
   375         // No data element matches the query. Ignore this result.
       
   376         if ( queryMatch == EFalse )
       
   377             {
       
   378             isMatch = EFalse;
       
   379             break;
       
   380             }
       
   381         }
       
   382 
       
   383     // If match add the element to the result set
       
   384     //  And before adding to the result set, check if there is atleast one match per query
       
   385     if ( isMatch && wordMatches >= mySearchQuery.Count() )
       
   386         {
       
   387         const TInt matchCount = tmpMatchSet.Count();
       
   388         for (TInt i = 0; i < matchCount; i++ )
       
   389             {
       
   390             aMatchedData.Append( *tmpMatchSet[i] );
       
   391             aMatchedData.Append( KSpace );
       
   392             }
       
   393         aMatchedData.TrimRight();
       
   394         }
       
   395 
       
   396     CleanupStack::PopAndDestroy( &tmpMatchSet ); // ResetAndDestroy
       
   397     CleanupStack::PopAndDestroy( &mySearchQuery ); // ResetAndDestroy
       
   398     CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy
       
   399     }
       
   400 
       
   401 // ----------------------------------------------------------------------------
       
   402 // CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL
       
   403 // Subset search function. Refer the above function for more description.
       
   404 // ----------------------------------------------------------------------------
       
   405 void CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, 
       
   406                                                           RPointerArray<CPcsPoolElement>& aSearchSet,
       
   407                                                           RPointerArray<CPsQuery>& aSearchQuery, 
       
   408                                                           TUint8 aFilteredDataMatch,
       
   409                                                           TBool aIsSearchInGroup, 
       
   410                                                           const RArray<TInt>& aContactsInGroup)
       
   411     {
       
   412     PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
       
   413 
       
   414     //__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
       
   415 
       
   416     TInt maxcount = 0;
       
   417     
       
   418     // Convert the individual queries to string form
       
   419     RPointerArray<CPsQuery> mySearchQuery;
       
   420     CleanupResetAndDestroyPushL( mySearchQuery );
       
   421 
       
   422     // Remember a temporary copy of query list
       
   423     // Copy the content of searchQuery
       
   424     const TInt searchQueryCount = aSearchQuery.Count(); 
       
   425     for (TInt i=0; i < searchQueryCount; i++)
       
   426         {
       
   427         CPsQuery* tempQuery = CPsQuery::NewL();
       
   428         CleanupStack::PushL( tempQuery );
       
   429         iAlgorithm->FindUtilECE()->GetPartOfQueryL(
       
   430                 *(aSearchQuery[i]), 0, aSearchQuery[i]->Count()-1, *tempQuery );
       
   431         mySearchQuery.AppendL(tempQuery);
       
   432         CleanupStack::Pop(tempQuery); // ownership transferred
       
   433         }
       
   434 
       
   435     // Sort the query items according to the length of each query 
       
   436     TLinearOrder<CPsQuery> rule(CPcsAlgorithm2Utils::CompareLength);
       
   437     mySearchQuery.Sort(rule);
       
   438 
       
   439     // To hold the match results
       
   440     RPointerArray<TDesC> tmpMatchSet;
       
   441     CleanupResetAndDestroyPushL( tmpMatchSet );
       
   442 
       
   443     // Parse thru each search set elements and filter the results
       
   444     const TInt searchSetCount = aSearchSet.Count(); 
       
   445     for (TInt index = 0; index < searchSetCount; index++)
       
   446         {
       
   447         CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (aSearchSet[index]);
       
   448         CPsData* psData = poolElement->GetPsData();
   459         CPsData* psData = poolElement->GetPsData();
   449         psData->ClearDataMatches();
   460         psData->ClearDataMatches();
   450 
   461 
   451         // Skip the contact if we are doing a group search and contact doesn't belong to the group
       
   452         if ( aIsSearchInGroup && 
       
   453              aContactsInGroup.Find( psData->Id() ) == KErrNotFound )
       
   454             {
       
   455             continue;
       
   456             }
       
   457         
       
   458         TBool isMatch = ETrue;
   462         TBool isMatch = ETrue;
   459         TInt wordMatches = 0;
   463         TUint8 wordMatches = 0;
   460 
   464 
   461         // Reset iWordMatches to zero 
   465         // Reset iWordMatches to zero 
   462         ClearWordMatches();
   466         ClearWordMatches();
   463 
   467 
   464         // Check for each query atleast one data element matches
   468         // Check for each query atleast one data element matches
   465         // Loop from the last query so that longest match is seen first
   469         // Loop from the last query so that longest match is seen first
   466         for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--)
   470         for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--)            
   467             {
   471             {
   468             TBool queryMatch = EFalse;
   472             TBool queryMatch = EFalse;
   469             CPsQuery* tmpPsQuery = mySearchQuery[queryIndex];
   473             CPsQuery* tmpPsQuery = mySearchQuery[queryIndex];
   470 
   474 
   471             const TInt dataElementCount = psData->DataElementCount();
   475             for (TInt dataIndex = 0; dataIndex < psData->DataElementCount(); dataIndex++)
   472             for (TInt dataIndex = 0; dataIndex < dataElementCount; dataIndex++)
       
   473                 {
   476                 {
   474                 // Filter off data fields not required in search
   477                 // Filter off data fields not required in search
   475                 TUint8 bitIndex = 1 << dataIndex;
   478                 TReal bitIndex;
   476                 TUint8 filter = bitIndex & aFilteredDataMatch;
   479                 Math::Pow(bitIndex, 2, dataIndex);
   477                 
   480 
   478                 // Omit the data fields which is not required in search
   481                 TUint8 filter = (TUint8) bitIndex & aFilteredDataMatch;
   479                 // or not matched with the pool element
   482                 if (filter == 0x0)
   480                 if ( filter == 0x0 ) 
       
   481                     {
   483                     {
   482                     // Move to next data
   484                     // Move to next data
   483                     continue;
   485                     continue;
   484                     }
   486                     }
   485 
   487 
   493                 // Search thru multiple words
   495                 // Search thru multiple words
   494                 while (tmpData.Length() != 0)
   496                 while (tmpData.Length() != 0)
   495                     {
   497                     {
   496                     wordIndex++;
   498                     wordIndex++;
   497                     
   499                     
       
   500                     TPtrC queryPtr = tmpPsQuery->QueryAsStringLC();
       
   501                     TBool matched = EFalse;
       
   502                     
       
   503                     if (keyboardMode == EModeUndefined)
       
   504                         {
       
   505                         matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery);
       
   506                         }
       
   507                     else if (keyboardMode == EItut)
       
   508                         {
       
   509                         matched = iAlgorithm->FindUtil()->Interface()->
       
   510                                   MatchRefineL(tmpData, queryPtr, ECustomConverter, iAlgorithm);
       
   511                         }
       
   512                     else // Qwerty
       
   513                         {
       
   514                         matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(tmpData, queryPtr);
       
   515                         
       
   516                         }
       
   517                     
       
   518                     CleanupStack::PopAndDestroy(); // queryPtr
       
   519                     
   498                     // Compare the data against query
   520                     // Compare the data against query
   499                     TBool matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery);
       
   500                     
       
   501                     if (matched)
   521                     if (matched)
   502                         {
   522                         {
   503                         psData->SetDataMatch(dataIndex);
   523                         psData->SetDataMatch(dataIndex);
   504 
   524 
   505                         // Perform two checks.
   525                         // Perform two checks.
   518                                 SetWordMap(dataIndex, wordIndex);
   538                                 SetWordMap(dataIndex, wordIndex);
   519                                 }
   539                                 }
   520 
   540 
   521                             // Extract matched character sequence and fill in temp array
   541                             // Extract matched character sequence and fill in temp array
   522                             TInt len = tmpPsQuery->Count();
   542                             TInt len = tmpPsQuery->Count();
   523                             if (iAlgorithm->FindUtilECE()->IsChineseWordIncluded(tmpData))
   543                             if (iAlgorithm->FindUtilECE()->IsChineseWord(tmpData))
   524                                 {
   544                                 {
   525                                 len = 1;
   545                                 len = 1;
   526                                 }
   546                                 }
   527 
   547 
   528                             TPtrC seq = tmpData.Left(len);
   548                             HBufC* seq = HBufC::NewL(len);
   529                             CPcsAlgorithm2Utils::AppendMatchToSeqL( tmpMatchSet, seq );
   549                             *seq = tmpData.Mid(0, len);
   530                             
   550 
   531                             // TODO: Match seqs could be extracted from actual
   551                             seq->Des().UpperCase();
   532                             //       match locations by using the other overload of
   552                             TIdentityRelation<TDesC> searchRule(Compare3);
   533                             //       CFindUtilChineseECE::MatchRefineL().
   553                             if (tmpMatchSet.Find(seq, searchRule) == KErrNotFound)
   534                             //       Currently, match seq data is not used by clients.
   554                                 {
       
   555                                 tmpMatchSet.Append(seq);
       
   556                                 }
       
   557                             else
       
   558                                 {
       
   559                                 delete seq;
       
   560                                 seq = NULL;
       
   561                                 }
   535                             }
   562                             }
   536                         }
   563                         }
   537 
   564 
   538                     // Next word
   565                     // Next word
   539                     tmpData.Set(lex.NextToken());
   566                     tmpData.Set(lex.NextToken());
   545                 {
   572                 {
   546                 isMatch = EFalse;
   573                 isMatch = EFalse;
   547                 break;
   574                 break;
   548                 }
   575                 }
   549             }
   576             }
   550         
       
   551 
   577 
   552         // If match add the element to the result set
   578         // If match add the element to the result set
   553         //  And before adding to the result set, check if there is atleast one match per query
   579         //  And before adding to the result set, check if there is atleast one match per query
   554         if ( isMatch && wordMatches >= mySearchQuery.Count() )
   580         if ((isMatch) && (wordMatches >= mySearchQuery.Count()))
   555             {
   581             {
   556             aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
   582             if (isSearchInGroup)
   557             maxcount++;
   583                 {
   558             }
   584                 if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
   559         
   585                     {
   560         if ( iMaxCount != -1 && maxcount > iMaxCount )
   586                     aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
   561             {
   587                     }
   562             break;
   588                 }
   563             }
   589             else
   564         
   590                 {
       
   591                 aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
       
   592                 }
       
   593             }
       
   594 
   565         // Cleanup the match sequence array as 
   595         // Cleanup the match sequence array as 
   566         // they are stored in pattern details structure
   596         // they are stored in pattern details structure
   567         tmpMatchSet.ResetAndDestroy();
   597         tmpMatchSet.ResetAndDestroy();
   568         }
   598         }
   569 
   599 
   570     CleanupStack::PopAndDestroy( &tmpMatchSet );   // ResetAndDestroy
   600     mySearchQuery.Reset();
   571     CleanupStack::PopAndDestroy( &mySearchQuery ); // ResetAndDestroy
       
   572 
       
   573     //__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
       
   574 
   601 
   575     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
   602     PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
   576     }
   603     }
   577 
   604 
   578 // ----------------------------------------------------------------------------
   605 // ----------------------------------------------------------------------------
   579 // CPcsAlgorithm2MultiSearchHelper::SetWordMap
   606 // CPcsAlgorithm2MultiSearchHelper::SetWordMap()
   580 // ----------------------------------------------------------------------------
   607 // ----------------------------------------------------------------------------
   581 void CPcsAlgorithm2MultiSearchHelper::SetWordMap(TInt aIndex, TInt aPosition)
   608 void CPcsAlgorithm2MultiSearchHelper::SetWordMap(TInt aIndex, TInt aPosition)
   582     {
   609     {
   583     TUint8 val = 1 << aPosition;
   610     TReal val;
   584     iWordMatches[aIndex] |= val;
   611     Math::Pow(val, 2, aPosition);
   585     }
   612 
   586 
   613     iWordMatches[aIndex] |= (TUint8) val;
   587 // ----------------------------------------------------------------------------
   614     }
   588 // CPcsAlgorithm2MultiSearchHelper::IsWordMatch
   615 
       
   616 // ----------------------------------------------------------------------------
       
   617 // CPcsAlgorithm2MultiSearchHelper::IsWordMatch()
   589 // ----------------------------------------------------------------------------
   618 // ----------------------------------------------------------------------------
   590 TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex)
   619 TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex)
   591     {
   620     {
   592     TUint8 val = 1 << aWordIndex;
   621     TReal val;
   593     return (iWordMatches[aDataIndex] & val);
   622     Math::Pow(val, 2, aWordIndex);
       
   623 
       
   624     return (iWordMatches[aDataIndex] & (TUint8) val);
       
   625     }
       
   626 
       
   627 // ----------------------------------------------------------------------------
       
   628 // CPcsAlgorithm2MultiSearchHelper::ExtractQueryL()
       
   629 // Extracts the query as a string. If the mode of query item is ITU numeric
       
   630 // character is used. Else the character is used.
       
   631 // ----------------------------------------------------------------------------
       
   632 void CPcsAlgorithm2MultiSearchHelper::ExtractQueryL(CPsQuery& aQuery, TDes& aOutput)
       
   633     {
       
   634     for (int i = 0; i < aQuery.Count(); i++)
       
   635         {
       
   636         if (aQuery.GetItemAtL(i).Mode() == EItut)
       
   637             {
       
   638             TBuf<KPsQueryMaxLen> outBuf;
       
   639             keyMap->GetNumericKeyString(aQuery.QueryAsStringLC(), outBuf);
       
   640             aOutput.Append(outBuf[i]);
       
   641             CleanupStack::PopAndDestroy();
       
   642             }
       
   643         else
       
   644             {
       
   645             aOutput.Append(aQuery.GetItemAtL(i).Character());
       
   646             }
       
   647         }
       
   648     }
       
   649 
       
   650 // ----------------------------------------------------------------------------
       
   651 // CPcsAlgorithm2MultiSearchHelper::ExtractQueryL()
       
   652 // Converts the input data refering the modes in the query.
       
   653 // If the mode of query item is ITU numeric character is used. Else the character
       
   654 // is used.
       
   655 // ----------------------------------------------------------------------------
       
   656 void CPcsAlgorithm2MultiSearchHelper::ExtractQueryL(TDesC& aInput, CPsQuery& aQuery, TDes& aOutput)
       
   657     {
       
   658     TInt len = -1;
       
   659 
       
   660     // Always loop thru the lowest length
       
   661     if (aInput.Length() > aQuery.Count())
       
   662         {
       
   663         len = aQuery.Count();
       
   664         }
       
   665     else
       
   666         {
       
   667         len = aInput.Length();
       
   668         }
       
   669 
       
   670     for (int i = 0; i < len; i++)
       
   671         {
       
   672         if (aQuery.GetItemAtL(i).Mode() == EItut)
       
   673             {
       
   674             TBuf<KPsQueryMaxLen> outBuf;
       
   675             keyMap->GetNumericKeyString(aInput, outBuf);
       
   676             aOutput.Append(outBuf[i]);
       
   677             }
       
   678         else
       
   679             {
       
   680             aOutput.Append(aInput[i]);
       
   681             }
       
   682         }
   594     }
   683     }
   595 
   684 
   596 // ----------------------------------------------------------------------------
   685 // ----------------------------------------------------------------------------
   597 // CPcsAlgorithm2MultiSearchHelper::BitsSet32
   686 // CPcsAlgorithm2MultiSearchHelper::BitsSet32
   598 // Helper funtion to count the number of bits set
   687 // Helper funtion to count the number of bits set
   608 
   697 
   609     return count;
   698     return count;
   610     }
   699     }
   611 
   700 
   612 // ----------------------------------------------------------------------------
   701 // ----------------------------------------------------------------------------
   613 // CPcsAlgorithm2MultiSearchHelper::ClearWordMatches
   702 // CPcsAlgorithm2MultiSearchHelper::BitsSet32
   614 // Function to reset the iWordMatches
   703 // Function to reset the iWordMatches
   615 // ----------------------------------------------------------------------------
   704 // ----------------------------------------------------------------------------
   616 void CPcsAlgorithm2MultiSearchHelper::ClearWordMatches()
   705 void CPcsAlgorithm2MultiSearchHelper::ClearWordMatches()
   617     {
   706     {
   618     for (TInt i = 0; i < MAX_DATA_FIELDS; i++)
   707     for (TInt i = 0; i < MAX_DATA_FIELDS; i++)
   638         // Skip separators before next word	                
   727         // Skip separators before next word	                
   639         if (!aQuery.GetItemAtL(beg).Character().IsSpace())
   728         if (!aQuery.GetItemAtL(beg).Character().IsSpace())
   640             {
   729             {
   641             // Scan the end of the word
   730             // Scan the end of the word
   642             TInt end = beg;
   731             TInt end = beg;
   643             while ( end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace() )
   732             for (; end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace(); ++end)
   644                 {
   733                 {
   645                 end++;
       
   646                 }
   734                 }
   647 
   735 
   648             // Create a new query object and append
   736             // Create a new query object and append
   649             CPsQuery* newQuery = CPsQuery::NewL();
   737             CPsQuery* newQuery = CPsQuery::NewL();
   650             for (TInt i = beg; i < end; i++)
   738             for (int i = beg; i < end; i++)
   651                 {
   739                 {
   652                 CPsQueryItem* item = CPsQueryItem::NewL();
   740                 CPsQueryItem* item = CPsQueryItem::NewL();
   653                 item->SetCharacter(aQuery.GetItemAtL(i).Character());
   741                 item->SetCharacter(aQuery.GetItemAtL(i).Character());
   654                 item->SetMode(aQuery.GetItemAtL(i).Mode());
   742                 item->SetMode(aQuery.GetItemAtL(i).Mode());
   655                 newQuery->AppendL(*item);
   743                 newQuery->AppendL(*item);
   662         }
   750         }
   663 
   751 
   664     return query;
   752     return query;
   665     }
   753     }
   666 
   754 
       
   755 // ----------------------------------------------------------------------------
       
   756 // CPcsAlgorithm2MultiSearchHelper::FilterDataFieldsL()
       
   757 // Constructs a bit pattern using the required/supported data fields
       
   758 // For example, 6, 4 and 27 are supported fields <-- 00000111
       
   759 //              6 and 4 are required fields      <-- 00000011
       
   760 // Bit pattern returned is 00000011.
       
   761 // ----------------------------------------------------------------------------
       
   762 TUint8 CPcsAlgorithm2MultiSearchHelper::FilterDataFieldsL(RArray<TInt>& aRequiredDataFields, 
       
   763                                                           RArray<TInt>& aSupportedDataFields)
       
   764     {
       
   765     TUint8 filteredMatch = 0x0;
       
   766 
       
   767     for (int i = 0; i < aSupportedDataFields.Count(); i++)
       
   768         {
       
   769         for (int j = 0; j < aRequiredDataFields.Count(); j++)
       
   770             {
       
   771             if (aSupportedDataFields[i] == aRequiredDataFields[j])
       
   772                 {
       
   773                 TReal val;
       
   774                 Math::Pow(val, 2, i);
       
   775 
       
   776                 filteredMatch |= (TUint8) val;
       
   777                 }
       
   778             }
       
   779         }
       
   780 
       
   781     return filteredMatch;
       
   782     }
       
   783 
   667 // End of file
   784 // End of file
   668 
   785 
   669 
   786