63
|
1 |
/*
|
|
2 |
* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
* All rights reserved.
|
|
4 |
* This component and the accompanying materials are made available
|
|
5 |
* under the terms of "Eclipse Public License v1.0"
|
|
6 |
* which accompanies this distribution, and is available
|
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
*
|
|
9 |
* Initial Contributors:
|
|
10 |
* Nokia Corporation - initial contribution.
|
|
11 |
*
|
|
12 |
* Contributors:
|
|
13 |
*
|
|
14 |
* Description: Supports initial search feature.
|
|
15 |
*
|
|
16 |
*/
|
|
17 |
|
|
18 |
// INCLUDES
|
|
19 |
#include "FindUtilChineseECE.h"
|
|
20 |
#include "CPcsAlgorithm2MultiSearchHelper.h"
|
|
21 |
#include "CPcsAlgorithm2Utils.h"
|
|
22 |
#include "CPcsDefs.h"
|
|
23 |
#include <collate.h>
|
|
24 |
#include <biditext.h>
|
|
25 |
|
|
26 |
|
|
27 |
// ============================== MEMBER FUNCTIONS ============================
|
|
28 |
|
|
29 |
// ----------------------------------------------------------------------------
|
|
30 |
// CPcsAlgorithm2MultiSearchHelper::NewL
|
|
31 |
// Two Phase Construction
|
|
32 |
// ----------------------------------------------------------------------------
|
|
33 |
CPcsAlgorithm2MultiSearchHelper* CPcsAlgorithm2MultiSearchHelper::NewL(CPcsAlgorithm2* aAlgorithm)
|
|
34 |
{
|
|
35 |
PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::NewL") );
|
|
36 |
|
|
37 |
CPcsAlgorithm2MultiSearchHelper* self = new (ELeave) CPcsAlgorithm2MultiSearchHelper();
|
|
38 |
CleanupStack::PushL(self);
|
|
39 |
self->ConstructL(aAlgorithm);
|
|
40 |
CleanupStack::Pop(self);
|
|
41 |
|
|
42 |
PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::NewL") );
|
|
43 |
|
|
44 |
return self;
|
|
45 |
}
|
|
46 |
|
|
47 |
// ----------------------------------------------------------------------------
|
|
48 |
// CPcsAlgorithm2MultiSearchHelper::CPcsAlgorithm2MultiSearchHelper
|
|
49 |
// Two Phase Construction
|
|
50 |
// ----------------------------------------------------------------------------
|
|
51 |
CPcsAlgorithm2MultiSearchHelper::CPcsAlgorithm2MultiSearchHelper()
|
|
52 |
{
|
|
53 |
PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::CPcsAlgorithm2") );
|
|
54 |
PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::CPcsAlgorithm2") );
|
|
55 |
}
|
|
56 |
|
|
57 |
// ----------------------------------------------------------------------------
|
|
58 |
// CPcsAlgorithm2MultiSearchHelper::ConstructL
|
|
59 |
// Two Phase Construction
|
|
60 |
// ----------------------------------------------------------------------------
|
|
61 |
void CPcsAlgorithm2MultiSearchHelper::ConstructL(CPcsAlgorithm2* aAlgorithm)
|
|
62 |
{
|
|
63 |
PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::ConstructL") );
|
|
64 |
|
|
65 |
iAlgorithm = aAlgorithm;
|
|
66 |
iKeyMap = iAlgorithm->GetKeyMap();
|
|
67 |
iMaxCount = 0;
|
|
68 |
|
|
69 |
PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::ConstructL") );
|
|
70 |
}
|
|
71 |
|
|
72 |
// ----------------------------------------------------------------------------
|
|
73 |
// CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper
|
|
74 |
// Destructor
|
|
75 |
// ----------------------------------------------------------------------------
|
|
76 |
CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper()
|
|
77 |
{
|
|
78 |
PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper") );
|
|
79 |
iMultiSearchResultsArr.ResetAndDestroy();
|
|
80 |
PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::~CPcsAlgorithm2MultiSearchHelper") );
|
|
81 |
}
|
|
82 |
|
|
83 |
// ----------------------------------------------------------------------------
|
|
84 |
// CPcsAlgorithm2MultiSearchHelper::SearchMultiL
|
|
85 |
// Initial search feature.
|
|
86 |
// Flow of steps in initial search is explained below.
|
|
87 |
// (1) Extract the pool elements corresponding to one of the queries.
|
|
88 |
// (2) Always the first query is used here.
|
|
89 |
// (3) Get pool elements from all caches corresponding to the data stores.
|
|
90 |
// (4) Convert each query to mode specific form.
|
|
91 |
// (5) Parse each data element.
|
|
92 |
// (6) Check for every search query atleast one data element matches.
|
|
93 |
// (7) If NOT ignore the result.
|
|
94 |
// (8) If so perform an additional check that number of data matches is
|
|
95 |
// atleast equal to number of search queries. This will ensure that same
|
|
96 |
// data element has not matched for multiple queries.
|
|
97 |
// (9) Now include the element in the result.
|
|
98 |
// ----------------------------------------------------------------------------
|
|
99 |
void CPcsAlgorithm2MultiSearchHelper::SearchMultiL(const CPsSettings& aSettings,
|
|
100 |
RPointerArray<CPsQuery>& aPsQuery,
|
|
101 |
TBool aIsSearchInGroup,
|
|
102 |
const RArray<TInt>& aContactsInGroup,
|
|
103 |
RPointerArray<CPsData>& aSearchResults,
|
|
104 |
RPointerArray<CPsPattern>& aSearchSeqs)
|
|
105 |
{
|
|
106 |
PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
|
|
107 |
|
|
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
|
|
114 |
TSortType sortType = aSettings.GetSortType();
|
|
115 |
CPcsAlgorithm2FilterHelper* filterHelper = CPcsAlgorithm2FilterHelper::NewL(sortType);
|
|
116 |
CleanupStack::PushL( filterHelper );
|
|
117 |
RPointerArray<CPcsPoolElement> elements;
|
|
118 |
CleanupClosePushL( elements );
|
|
119 |
|
|
120 |
iMultiSearchResultsArr.ResetAndDestroy();
|
|
121 |
|
|
122 |
// Get the data stores
|
|
123 |
RPointerArray<TDesC> dataStores;
|
|
124 |
CleanupResetAndDestroyPushL( dataStores );
|
|
125 |
aSettings.SearchUrisL(dataStores);
|
|
126 |
|
|
127 |
// Get the required display fields from the client
|
|
128 |
RArray<TInt> requiredDataFields;
|
|
129 |
CleanupClosePushL( requiredDataFields );
|
|
130 |
aSettings.DisplayFieldsL(requiredDataFields);
|
|
131 |
|
|
132 |
// Search from cache based on first character of 1st item in query list
|
|
133 |
const CPsQueryItem& firstCharItem = aPsQuery[0]->GetItemAtL(0);
|
|
134 |
TInt cachePoolId = iKeyMap->PoolIdForCharacter( firstCharItem.Character(), firstCharItem.Mode() );
|
|
135 |
|
|
136 |
// Get the elements from all the databases
|
|
137 |
const TInt dataStoresCount = dataStores.Count();
|
|
138 |
for (TInt dsIndex = 0; dsIndex < dataStoresCount; dsIndex++)
|
|
139 |
{
|
|
140 |
RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
|
|
141 |
iMultiSearchResultsArr.Append(temp);
|
|
142 |
|
|
143 |
// Get the contents for this data store
|
|
144 |
TInt arrayIndex = iAlgorithm->GetCacheIndex(*(dataStores[dsIndex]));
|
|
145 |
if (arrayIndex < 0)
|
|
146 |
{
|
|
147 |
continue;
|
|
148 |
}
|
|
149 |
CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
|
|
150 |
cache->GetContactsForKeyL(cachePoolId, elements);
|
|
151 |
|
|
152 |
// Get the supported data fields for this data store
|
|
153 |
RArray<TInt> supportedDataFields;
|
|
154 |
CleanupClosePushL( supportedDataFields );
|
|
155 |
cache->GetDataFields(supportedDataFields);
|
|
156 |
|
|
157 |
// Get the filtered data fields for this data store
|
|
158 |
TUint8 filteredDataMatch = CPcsAlgorithm2Utils::FilterDataFieldsL(
|
|
159 |
requiredDataFields, supportedDataFields);
|
|
160 |
|
|
161 |
// Filter the results now
|
|
162 |
FilterResultsMultiL(filterHelper,
|
|
163 |
elements,
|
|
164 |
aPsQuery,
|
|
165 |
filteredDataMatch,
|
|
166 |
aIsSearchInGroup,
|
|
167 |
aContactsInGroup);
|
|
168 |
|
|
169 |
// If alphabetical sorting, get the results for this datastore
|
|
170 |
if (sortType == EAlphabetical)
|
|
171 |
{
|
|
172 |
filterHelper->GetResults(*(iMultiSearchResultsArr[dsIndex]));
|
|
173 |
}
|
|
174 |
|
|
175 |
elements.Reset();
|
|
176 |
CleanupStack::PopAndDestroy( &supportedDataFields ); // Close
|
|
177 |
}
|
|
178 |
CleanupStack::PopAndDestroy( &requiredDataFields ); // Close
|
|
179 |
CleanupStack::PopAndDestroy( &dataStores ); // ResetAndDestroy
|
|
180 |
|
|
181 |
// If alphabetical sorting, merge the result sets of all datastores
|
|
182 |
if (sortType == EAlphabetical)
|
|
183 |
{
|
|
184 |
// Form the complete searchResults array
|
|
185 |
CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iMultiSearchResultsArr,
|
|
186 |
aSearchResults);
|
|
187 |
}
|
|
188 |
else
|
|
189 |
{
|
|
190 |
// Results are already sorted patternbased
|
|
191 |
filterHelper->GetResults(aSearchResults);
|
|
192 |
}
|
|
193 |
|
|
194 |
// Get the sorted match sequence list
|
|
195 |
filterHelper->GetPatternsL(aSearchSeqs);
|
|
196 |
|
|
197 |
PRINT1 ( _L("Number of search results = %d"), aSearchResults.Count() );
|
|
198 |
|
|
199 |
// Cleanup
|
|
200 |
for (TInt i = 0; i < iMultiSearchResultsArr.Count(); i++)
|
|
201 |
{
|
|
202 |
iMultiSearchResultsArr[i]->Reset();
|
|
203 |
delete iMultiSearchResultsArr[i];
|
|
204 |
iMultiSearchResultsArr[i] = NULL;
|
|
205 |
}
|
|
206 |
|
|
207 |
iMultiSearchResultsArr.Reset();
|
|
208 |
CleanupStack::PopAndDestroy( &elements ); // Close
|
|
209 |
CleanupStack::PopAndDestroy( filterHelper );
|
|
210 |
|
|
211 |
//__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
|
|
212 |
|
|
213 |
PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMultiL") );
|
|
214 |
}
|
|
215 |
|
|
216 |
// ----------------------------------------------------------------------------
|
|
217 |
// CPcsAlgorithm1MultiSearchHelper::SearchMatchSeqMultiL
|
|
218 |
// Function adds matches, and locations based on multi query, and data
|
|
219 |
// Duplicate locations are allowed (as they are removed later anyway)
|
|
220 |
// Post condition locations in index order
|
|
221 |
// ----------------------------------------------------------------------------
|
|
222 |
void CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL( RPointerArray<CPsQuery>& aPsQuery,
|
|
223 |
const TDesC& aData,
|
|
224 |
RPointerArray<TDesC>& aMatchSeq,
|
|
225 |
RArray<TPsMatchLocation>& aMatchLocation )
|
|
226 |
{
|
|
227 |
PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
|
|
228 |
|
|
229 |
TLex lex(aData);
|
|
230 |
while ( !lex.Eos() ) // Search thru all words
|
|
231 |
{
|
|
232 |
TPtrC currentWord = lex.NextToken(); // next word
|
|
233 |
|
|
234 |
const TInt psQueryCount = aPsQuery.Count();
|
|
235 |
for ( TInt queryIndex = 0; queryIndex < psQueryCount; ++queryIndex )
|
|
236 |
{
|
|
237 |
CPsQuery* currentQuery = aPsQuery[queryIndex];
|
|
238 |
|
|
239 |
RArray<TInt> matchPos;
|
|
240 |
CleanupClosePushL( matchPos );
|
|
241 |
RArray<TInt> matchLen;
|
|
242 |
CleanupClosePushL( matchLen );
|
|
243 |
|
|
244 |
if ( iAlgorithm->FindUtilECE()->MatchRefineL( currentWord, *currentQuery, matchPos, matchLen, ETrue ) )
|
|
245 |
{
|
|
246 |
// Some matches found. Add all of them to result array.
|
|
247 |
ASSERT( matchPos.Count() == matchLen.Count() );
|
|
248 |
|
|
249 |
TInt wordStartPos = lex.Offset() - currentWord.Length();
|
|
250 |
const TInt matchPosCount = matchPos.Count();
|
|
251 |
for ( TInt i = 0 ; i < matchPosCount; ++i )
|
|
252 |
{
|
|
253 |
TPsMatchLocation newLocation = { wordStartPos + matchPos[i], matchLen[i],
|
|
254 |
TBidiText::TextDirectionality(currentWord) };
|
|
255 |
aMatchLocation.AppendL( newLocation );
|
|
256 |
|
|
257 |
TPtrC matchPart = currentWord.Mid( matchPos[i], matchLen[i] );
|
|
258 |
CPcsAlgorithm2Utils::AppendMatchToSeqL( aMatchSeq, matchPart );
|
|
259 |
}
|
|
260 |
}
|
|
261 |
|
|
262 |
CleanupStack::PopAndDestroy( &matchLen );
|
|
263 |
CleanupStack::PopAndDestroy( &matchPos );
|
|
264 |
}
|
|
265 |
}
|
|
266 |
|
|
267 |
PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::SearchMatchSeqMultiL") );
|
|
268 |
}
|
|
269 |
|
|
270 |
// ----------------------------------------------------------------------------
|
|
271 |
// CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL
|
|
272 |
// Subset search function. Refer the above function for more description.
|
|
273 |
// ----------------------------------------------------------------------------
|
|
274 |
void CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper,
|
|
275 |
RPointerArray<CPcsPoolElement>& aSearchSet,
|
|
276 |
RPointerArray<CPsQuery>& aSearchQuery,
|
|
277 |
TUint8 aFilteredDataMatch,
|
|
278 |
TBool aIsSearchInGroup,
|
|
279 |
const RArray<TInt>& aContactsInGroup)
|
|
280 |
{
|
|
281 |
PRINT ( _L("Enter CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
|
|
282 |
|
|
283 |
//__LATENCY_MARK ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
|
|
284 |
|
|
285 |
TInt maxcount = 0;
|
|
286 |
|
|
287 |
// Convert the individual queries to string form
|
|
288 |
RPointerArray<CPsQuery> mySearchQuery;
|
|
289 |
CleanupResetAndDestroyPushL( mySearchQuery );
|
|
290 |
|
|
291 |
// Remember a temporary copy of query list
|
|
292 |
// Copy the content of searchQuery
|
|
293 |
const TInt searchQueryCount = aSearchQuery.Count();
|
|
294 |
for (TInt i=0; i < searchQueryCount; i++)
|
|
295 |
{
|
|
296 |
CPsQuery* tempQuery = CPsQuery::NewL();
|
|
297 |
CleanupStack::PushL( tempQuery );
|
|
298 |
iAlgorithm->FindUtilECE()->GetPartOfQueryL(
|
|
299 |
*(aSearchQuery[i]), 0, aSearchQuery[i]->Count()-1, *tempQuery );
|
|
300 |
mySearchQuery.AppendL(tempQuery);
|
|
301 |
CleanupStack::Pop(tempQuery); // ownership transferred
|
|
302 |
}
|
|
303 |
|
|
304 |
// Sort the query items according to the length of each query
|
|
305 |
TLinearOrder<CPsQuery> rule(CPcsAlgorithm2Utils::CompareLength);
|
|
306 |
mySearchQuery.Sort(rule);
|
|
307 |
|
|
308 |
// To hold the match results
|
|
309 |
RPointerArray<TDesC> tmpMatchSet;
|
|
310 |
CleanupResetAndDestroyPushL( tmpMatchSet );
|
|
311 |
|
|
312 |
// Parse thru each search set elements and filter the results
|
|
313 |
const TInt searchSetCount = aSearchSet.Count();
|
|
314 |
for (TInt index = 0; index < searchSetCount; index++)
|
|
315 |
{
|
|
316 |
CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (aSearchSet[index]);
|
|
317 |
CPsData* psData = poolElement->GetPsData();
|
|
318 |
psData->ClearDataMatches();
|
|
319 |
|
|
320 |
// Skip the contact if we are doing a group search and contact doesn't belong to the group
|
|
321 |
if ( aIsSearchInGroup &&
|
|
322 |
aContactsInGroup.Find( psData->Id() ) == KErrNotFound )
|
|
323 |
{
|
|
324 |
continue;
|
|
325 |
}
|
|
326 |
|
|
327 |
TBool isMatch = ETrue;
|
|
328 |
TInt wordMatches = 0;
|
|
329 |
|
|
330 |
// Reset iWordMatches to zero
|
|
331 |
ClearWordMatches();
|
|
332 |
|
|
333 |
// Check for each query atleast one data element matches
|
|
334 |
// Loop from the last query so that longest match is seen first
|
|
335 |
for (TInt queryIndex = mySearchQuery.Count() - 1; queryIndex >= 0; queryIndex--)
|
|
336 |
{
|
|
337 |
TBool queryMatch = EFalse;
|
|
338 |
CPsQuery* tmpPsQuery = mySearchQuery[queryIndex];
|
|
339 |
|
|
340 |
const TInt dataElementCount = psData->DataElementCount();
|
|
341 |
for (TInt dataIndex = 0; dataIndex < dataElementCount; dataIndex++)
|
|
342 |
{
|
|
343 |
// Filter off data fields not required in search
|
|
344 |
TUint8 bitIndex = 1 << dataIndex;
|
|
345 |
TUint8 filter = bitIndex & aFilteredDataMatch;
|
|
346 |
|
|
347 |
// Omit the data fields which is not required in search
|
|
348 |
// or not matched with the pool element
|
|
349 |
if ( filter == 0x0 )
|
|
350 |
{
|
|
351 |
// Move to next data
|
|
352 |
continue;
|
|
353 |
}
|
|
354 |
|
|
355 |
TInt wordIndex = -1;
|
|
356 |
|
|
357 |
TLex lex(psData->Data(dataIndex)->Des());
|
|
358 |
|
|
359 |
// First word
|
|
360 |
TPtrC tmpData = lex.NextToken();
|
|
361 |
|
|
362 |
// Search thru multiple words
|
|
363 |
while (tmpData.Length() != 0)
|
|
364 |
{
|
|
365 |
wordIndex++;
|
|
366 |
|
|
367 |
// Compare the data against query
|
|
368 |
TBool matched = iAlgorithm->FindUtilECE()->MatchRefineL(tmpData, *tmpPsQuery);
|
|
369 |
|
|
370 |
if (matched)
|
|
371 |
{
|
|
372 |
psData->SetDataMatch(dataIndex);
|
|
373 |
|
|
374 |
// Perform two checks.
|
|
375 |
// 1. Ensure that the word is not matched against any previous query
|
|
376 |
// 2. If it is the first match to the query
|
|
377 |
TBool isWordMatch = IsWordMatch(dataIndex, wordIndex);
|
|
378 |
|
|
379 |
// Check if the current word is not matched to any query
|
|
380 |
if (!isWordMatch)
|
|
381 |
{
|
|
382 |
// Check if no word is matched for this query till now
|
|
383 |
if (!queryMatch)
|
|
384 |
{
|
|
385 |
wordMatches++;
|
|
386 |
queryMatch = ETrue;
|
|
387 |
SetWordMap(dataIndex, wordIndex);
|
|
388 |
}
|
|
389 |
|
|
390 |
// Extract matched character sequence and fill in temp array
|
|
391 |
TInt len = tmpPsQuery->Count();
|
|
392 |
if (iAlgorithm->FindUtilECE()->IsChineseWordIncluded(tmpData))
|
|
393 |
{
|
|
394 |
len = 1;
|
|
395 |
}
|
|
396 |
|
|
397 |
TPtrC seq = tmpData.Left(len);
|
|
398 |
CPcsAlgorithm2Utils::AppendMatchToSeqL( tmpMatchSet, seq );
|
|
399 |
|
|
400 |
// TODO: Match seqs could be extracted from actual
|
|
401 |
// match locations by using the other overload of
|
|
402 |
// CFindUtilChineseECE::MatchRefineL().
|
|
403 |
// Currently, match seq data is not used by clients.
|
|
404 |
}
|
|
405 |
}
|
|
406 |
|
|
407 |
// Next word
|
|
408 |
tmpData.Set(lex.NextToken());
|
|
409 |
}
|
|
410 |
}
|
|
411 |
|
|
412 |
// No data element matches the query. Ignore this result.
|
|
413 |
if (queryMatch == EFalse)
|
|
414 |
{
|
|
415 |
isMatch = EFalse;
|
|
416 |
break;
|
|
417 |
}
|
|
418 |
}
|
|
419 |
|
|
420 |
|
|
421 |
// If match add the element to the result set
|
|
422 |
// And before adding to the result set, check if there is atleast one match per query
|
|
423 |
if ( isMatch && wordMatches >= mySearchQuery.Count() )
|
|
424 |
{
|
|
425 |
aAlgorithmFilterHelper->AddL(psData, tmpMatchSet);
|
|
426 |
maxcount++;
|
|
427 |
}
|
|
428 |
|
|
429 |
if ( iMaxCount != -1 && maxcount > iMaxCount )
|
|
430 |
{
|
|
431 |
break;
|
|
432 |
}
|
|
433 |
|
|
434 |
// Cleanup the match sequence array as
|
|
435 |
// they are stored in pattern details structure
|
|
436 |
tmpMatchSet.ResetAndDestroy();
|
|
437 |
}
|
|
438 |
|
|
439 |
CleanupStack::PopAndDestroy( &tmpMatchSet ); // ResetAndDestroy
|
|
440 |
CleanupStack::PopAndDestroy( &mySearchQuery ); // ResetAndDestroy
|
|
441 |
|
|
442 |
//__LATENCY_MARKEND ( _L("CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
|
|
443 |
|
|
444 |
PRINT ( _L("End CPcsAlgorithm2MultiSearchHelper::FilterResultsMultiL") );
|
|
445 |
}
|
|
446 |
|
|
447 |
// ----------------------------------------------------------------------------
|
|
448 |
// CPcsAlgorithm2MultiSearchHelper::SetWordMap
|
|
449 |
// ----------------------------------------------------------------------------
|
|
450 |
void CPcsAlgorithm2MultiSearchHelper::SetWordMap(TInt aIndex, TInt aPosition)
|
|
451 |
{
|
|
452 |
TUint8 val = 1 << aPosition;
|
|
453 |
iWordMatches[aIndex] |= val;
|
|
454 |
}
|
|
455 |
|
|
456 |
// ----------------------------------------------------------------------------
|
|
457 |
// CPcsAlgorithm2MultiSearchHelper::IsWordMatch
|
|
458 |
// ----------------------------------------------------------------------------
|
|
459 |
TBool CPcsAlgorithm2MultiSearchHelper::IsWordMatch(TInt aDataIndex, TInt aWordIndex)
|
|
460 |
{
|
|
461 |
TUint8 val = 1 << aWordIndex;
|
|
462 |
return (iWordMatches[aDataIndex] & val);
|
|
463 |
}
|
|
464 |
|
|
465 |
// ----------------------------------------------------------------------------
|
|
466 |
// CPcsAlgorithm2MultiSearchHelper::BitsSet32
|
|
467 |
// Helper funtion to count the number of bits set
|
|
468 |
// ----------------------------------------------------------------------------
|
|
469 |
TInt CPcsAlgorithm2MultiSearchHelper::BitsSet32(TUint32 aData)
|
|
470 |
{
|
|
471 |
TInt count = 0;
|
|
472 |
|
|
473 |
for (count = 0; aData; aData &= (aData - 1))
|
|
474 |
{
|
|
475 |
count++;
|
|
476 |
}
|
|
477 |
|
|
478 |
return count;
|
|
479 |
}
|
|
480 |
|
|
481 |
// ----------------------------------------------------------------------------
|
|
482 |
// CPcsAlgorithm2MultiSearchHelper::ClearWordMatches
|
|
483 |
// Function to reset the iWordMatches
|
|
484 |
// ----------------------------------------------------------------------------
|
|
485 |
void CPcsAlgorithm2MultiSearchHelper::ClearWordMatches()
|
|
486 |
{
|
|
487 |
for (TInt i = 0; i < MAX_DATA_FIELDS; i++)
|
|
488 |
iWordMatches[i] = 0;
|
|
489 |
}
|
|
490 |
|
|
491 |
// ----------------------------------------------------------------------------
|
|
492 |
// CPcsAlgorithm2MultiSearchHelper::MultiQuery
|
|
493 |
// Checks if the query object has multiple queries embedded.
|
|
494 |
// Seperator used is a space.
|
|
495 |
// Scans through each query character and creates a new query object on a space.
|
|
496 |
// Consequtive spaces are skipped.
|
|
497 |
// Returns an array of query objects.
|
|
498 |
// ----------------------------------------------------------------------------
|
|
499 |
RPointerArray<CPsQuery> CPcsAlgorithm2MultiSearchHelper::MultiQueryL(CPsQuery& aQuery)
|
|
500 |
{
|
|
501 |
RPointerArray<CPsQuery> query;
|
|
502 |
|
|
503 |
const TInt textLength = aQuery.Count();
|
|
504 |
|
|
505 |
for (TInt beg = 0; beg < textLength; ++beg)
|
|
506 |
{
|
|
507 |
// Skip separators before next word
|
|
508 |
if (!aQuery.GetItemAtL(beg).Character().IsSpace())
|
|
509 |
{
|
|
510 |
// Scan the end of the word
|
|
511 |
TInt end = beg;
|
|
512 |
while ( end < textLength && !aQuery.GetItemAtL(end).Character().IsSpace() )
|
|
513 |
{
|
|
514 |
end++;
|
|
515 |
}
|
|
516 |
|
|
517 |
// Create a new query object and append
|
|
518 |
CPsQuery* newQuery = CPsQuery::NewL();
|
|
519 |
for (TInt i = beg; i < end; i++)
|
|
520 |
{
|
|
521 |
CPsQueryItem* item = CPsQueryItem::NewL();
|
|
522 |
item->SetCharacter(aQuery.GetItemAtL(i).Character());
|
|
523 |
item->SetMode(aQuery.GetItemAtL(i).Mode());
|
|
524 |
newQuery->AppendL(*item);
|
|
525 |
}
|
|
526 |
query.Append(newQuery);
|
|
527 |
|
|
528 |
// Scan for next word
|
|
529 |
beg = end;
|
|
530 |
}
|
|
531 |
}
|
|
532 |
|
|
533 |
return query;
|
|
534 |
}
|
|
535 |
|
|
536 |
// End of file
|
|
537 |
|
|
538 |
|