32 // ---------------------------------------------------------------------------- |
31 // ---------------------------------------------------------------------------- |
33 // CPcsAlgorithm2Utils::FormCompleteSearchResultsL() |
32 // CPcsAlgorithm2Utils::FormCompleteSearchResultsL() |
34 // Merges all the respective data store result sets to single set in sorted order. |
33 // Merges all the respective data store result sets to single set in sorted order. |
35 // ---------------------------------------------------------------------------- |
34 // ---------------------------------------------------------------------------- |
36 void CPcsAlgorithm2Utils::FormCompleteSearchResultsL(RPointerArray<CPSDATA_R_PTR_ARRAY>& aSearchResultsArr, |
35 void CPcsAlgorithm2Utils::FormCompleteSearchResultsL(RPointerArray<CPSDATA_R_PTR_ARRAY>& aSearchResultsArr, |
37 RPointerArray<CPsData>& aSearchResults) |
36 RPointerArray<CPsData>& SearchResults) |
38 { |
37 { |
|
38 CleanupClosePushL( SearchResults ); |
|
39 |
39 TInt maxIndex = 0; |
40 TInt maxIndex = 0; |
40 TInt maxValue = aSearchResultsArr[maxIndex]->Count(); |
41 TInt maxValue = aSearchResultsArr[maxIndex]->Count(); |
41 TLinearOrder<CPsData> rule(CPcsAlgorithm2Utils::CompareDataBySortOrderL); |
42 TLinearOrder<CPsData> rule(CPcsAlgorithm2Utils::CompareDataBySortOrder); |
42 |
43 |
43 // Find the largest array in aSearchResultsArr |
44 // Find the largest array in aSearchResultsArr |
44 const TInt searchResultsArrCount = aSearchResultsArr.Count(); |
45 for (TInt i = 1; i < aSearchResultsArr.Count(); i++) |
45 for (TInt i = 1; i < searchResultsArrCount; i++) |
|
46 { |
46 { |
47 if (aSearchResultsArr[i]->Count() > maxValue) |
47 if (aSearchResultsArr[i]->Count() > maxValue) |
48 { |
48 { |
49 maxIndex = i; |
49 maxIndex = i; |
50 maxValue = aSearchResultsArr[i]->Count(); |
50 maxValue = aSearchResultsArr[i]->Count(); |
51 } |
51 } |
52 } |
52 } |
53 |
53 |
54 // Assign the largets array to searchresults |
54 // Assign the largets array to searchresults |
55 const TInt cnt = aSearchResultsArr[maxIndex]->Count(); |
55 for (TInt i = 0; i < aSearchResultsArr[maxIndex]->Count(); i++) |
56 for (TInt i = 0; i < cnt; i++) |
56 { |
57 { |
57 SearchResults.Append((*(aSearchResultsArr[maxIndex]))[i]); |
58 aSearchResults.Append((*(aSearchResultsArr[maxIndex]))[i]); |
|
59 } |
58 } |
60 |
59 |
61 // Merge the remaining result arrays to the largest array in sequential order |
60 // Merge the remaining result arrays to the largest array in sequential order |
62 |
61 for (TInt i = 0; i < aSearchResultsArr.Count(); i++) |
63 for (TInt i = 0; i < searchResultsArrCount; i++) |
|
64 { |
62 { |
65 // Check if we are not copying again the largest array |
63 // Check if we are not copying again the largest array |
66 if ((i != maxIndex) && ((aSearchResultsArr[i])->Count() != 0)) |
64 if ((i != maxIndex) && ((aSearchResultsArr[i])->Count() != 0)) |
67 { |
65 { |
68 TInt numElements = (aSearchResultsArr[i])->Count(); |
66 TInt numElements = (aSearchResultsArr[i])->Count(); |
69 for (TInt j = 0; j < numElements; j++) |
67 for (TInt j = 0; j < numElements; j++) |
70 { |
68 { |
71 aSearchResults.InsertInOrderAllowRepeatsL((*(aSearchResultsArr[i]))[j], rule); |
69 SearchResults.InsertInOrderAllowRepeatsL((*(aSearchResultsArr[i]))[j], rule); |
72 } |
70 } |
73 } |
71 } |
74 } |
72 } |
|
73 CleanupStack::Pop(); |
75 } |
74 } |
76 |
75 |
77 // ---------------------------------------------------------------------------- |
76 // ---------------------------------------------------------------------------- |
78 // CPcsAlgorithm2Utils::MyCompareC() |
77 // CPcsAlgorithm2Utils::MyCompareC() |
79 // Lang specific MyCompareC |
78 // Lang specific MyCompareC |
97 TInt comparison(aLeft.CompareC(aRight, 3, &meth)); |
96 TInt comparison(aLeft.CompareC(aRight, 3, &meth)); |
98 return comparison; |
97 return comparison; |
99 } |
98 } |
100 |
99 |
101 // ---------------------------------------------------------------------------- |
100 // ---------------------------------------------------------------------------- |
102 // CPcsAlgorithm2Utils::CompareDataBySortOrderL() |
101 // CPcsAlgorithm2Utils::CompareDataBySortOrder() |
103 // TLinearOrder rule for comparison of data objects |
102 // TLinearOrder rule for comparison of data objects |
104 // ---------------------------------------------------------------------------- |
103 // ---------------------------------------------------------------------------- |
105 TInt CPcsAlgorithm2Utils::CompareDataBySortOrderL(const CPsData& aObject1, |
104 TInt CPcsAlgorithm2Utils::CompareDataBySortOrder(const CPsData& aObject1, |
106 const CPsData& aObject2) |
105 const CPsData& aObject2) |
107 { |
106 { |
108 TInt compareRes = 0; |
107 _LIT(KSpace, " "); |
109 |
|
110 if( CPsData::CompareById(aObject1, aObject2) ) |
|
111 { |
|
112 return compareRes; |
|
113 } |
|
114 |
108 |
115 // Fetch the cache list stored in TLS to recover the sort order |
109 // Fetch the cache list stored in TLS to recover the sort order |
116 typedef RPointerArray<CPcsCache> PTR; |
110 typedef RPointerArray<CPcsCache> PTR; |
117 PTR* pcsCache = static_cast<PTR*>(Dll::Tls()); |
111 PTR* pcsCache = static_cast<PTR*> (Dll::Tls()); |
118 User::LeaveIfNull(pcsCache); |
112 |
119 |
113 // Data1 |
120 CPcsCache* cache1 = (*pcsCache)[aObject1.UriId()]; |
114 TBuf<255> data1(KNullDesC); |
121 CPcsCache* cache2 = (*pcsCache)[aObject2.UriId()]; |
115 TInt uriId1 = aObject1.UriId(); |
122 RArray<TInt> indexOrder1; |
116 CPcsCache* cache = (*pcsCache)[uriId1]; |
123 RArray<TInt> indexOrder2; |
117 |
|
118 RArray<TInt> indexOrder; |
124 |
119 |
125 // Get the index order based on sort order from the cache |
120 // Get the index order based on sort order from the cache |
126 cache1->GetIndexOrder(indexOrder1); |
121 cache->GetIndexOrder(indexOrder); |
127 CleanupClosePushL(indexOrder1); |
122 |
128 cache2->GetIndexOrder(indexOrder2); |
123 // Append sort order elements first |
129 CleanupClosePushL(indexOrder2); |
124 for (int i = 0; i < indexOrder.Count(); i++) |
130 |
125 { |
131 // Check if Sort Order is identical (it must be for same cache) |
126 TInt index = indexOrder[i]; |
132 TBool sameIndexOrder = ETrue; |
127 if (index < aObject1.DataElementCount() && aObject1.Data(index)) |
133 if ( indexOrder1.Count() != indexOrder2.Count() ) |
128 { |
134 { |
129 // Trim the unnecessary white spaces/special chars before we compare |
135 sameIndexOrder = EFalse; |
130 TBuf<255> str(KNullDesC); |
136 } |
131 |
137 else |
132 str = aObject1.Data(index)->Des(); |
138 { |
133 CPcsAlgorithm2Utils::MyTrim(str); |
139 for ( TInt i = 0; i < indexOrder1.Count(); i++ ) |
134 |
140 { |
135 data1 += str; |
141 if (indexOrder1[i] != indexOrder2[i]) |
136 data1 += KSpace; |
142 { |
137 } |
143 sameIndexOrder = EFalse; |
138 } |
144 break; |
139 |
145 } |
140 /* --- NOT SURE IF THIS BEHAVIOR IS REQUIRED --- |
146 } |
141 // Append remaining elements in order |
147 } |
142 for ( int i = 0; i < aObject1.DataElementCount(); i++ ) |
148 |
143 { |
149 // Sort Orders among diffent caches should be the same, anyway |
144 if ( indexOrder.Find(i) == KErrNone && aObject1.Data(i) ) |
150 // if caches and SO are different we compare by cache URI index |
145 { |
151 if (!sameIndexOrder) |
146 data1 += aObject1.Data(i)->Des(); |
152 { |
147 data1 += KSpace; |
153 compareRes = aObject1.UriId() - aObject2.UriId(); |
148 } |
154 |
149 } |
155 CleanupStack::PopAndDestroy(&indexOrder2); |
150 */ |
156 CleanupStack::PopAndDestroy(&indexOrder1); |
151 |
157 return compareRes; |
152 // Data2 |
158 } |
153 TBuf<255> data2(KNullDesC); |
159 |
154 TInt uriId2 = aObject2.UriId(); |
160 // The comparison between contacts data is done for the sort order |
155 cache = (*pcsCache)[uriId2]; |
161 // fields skipping the ones that are empty |
156 |
162 TInt indexCount = indexOrder1.Count(); |
157 indexOrder.Reset(); |
163 TInt idx1 = 0; |
158 |
164 TInt idx2 = 0; |
159 // Get the index order based on sort order from the cache |
165 while ( compareRes == 0 && idx1 < indexCount && idx2 < indexCount ) |
160 cache->GetIndexOrder(indexOrder); |
166 { |
161 |
167 // Get contact field of 1st contact |
162 // Append sort order elements first |
168 TInt object1Idx = indexOrder1[idx1]; |
163 for (int i = 0; i < indexOrder.Count(); i++) |
169 HBufC* strCompare1 = aObject1.Data(object1Idx)->Des().AllocLC(); |
164 { |
170 TPtr strCompare1Ptr( strCompare1->Des() ); |
165 TInt index = indexOrder[i]; |
171 CPcsAlgorithm2Utils::MyTrim( strCompare1Ptr ); |
166 if (index < aObject2.DataElementCount() && aObject2.Data(index)) |
172 |
167 { |
173 // Get contact field of 2nd contact |
168 // Trim the unnecessary white spaces/special chars before we compare |
174 TInt object2Idx = indexOrder2[idx2]; |
169 TBuf<255> str(KNullDesC); |
175 HBufC* strCompare2 = aObject2.Data(object2Idx)->Des().AllocLC(); |
170 |
176 TPtr strCompare2Ptr( strCompare2->Des() ); |
171 str = aObject2.Data(index)->Des(); |
177 CPcsAlgorithm2Utils::MyTrim( strCompare2Ptr ); |
172 CPcsAlgorithm2Utils::MyTrim(str); |
178 |
173 |
179 if ( strCompare1->Length() > 0 && strCompare2->Length() > 0 ) |
174 data2 += str; |
180 { |
175 data2 += KSpace; |
181 compareRes = CPcsAlgorithm2Utils::MyCompareC(*strCompare1, *strCompare2); |
176 } |
182 idx1++; |
177 } |
183 idx2++; |
178 |
184 } |
179 /* --- NOT SURE IF THIS BEHAVIOR IS REQUIRED --- |
185 else // Increment only the index of the contact with empty field |
180 // Append remaining elements in order |
186 { |
181 for ( int i = 0; i < aObject2.DataElementCount(); i++ ) |
187 if ( strCompare1->Length() == 0 ) |
182 { |
188 idx1++; |
183 if ( indexOrder.Find(i) == KErrNone && aObject2.Data(i) ) |
189 if ( strCompare2->Length() == 0 ) |
184 { |
190 idx2++; |
185 data2 += aObject2.Data(i)->Des(); |
191 } |
186 data2 += KSpace; |
192 |
187 } |
193 CleanupStack::PopAndDestroy(strCompare2); |
188 } |
194 CleanupStack::PopAndDestroy(strCompare1); |
189 */ |
195 } |
190 |
196 |
191 indexOrder.Reset(); |
197 // We do not return that contacts are equal by SO |
192 data1.TrimAll(); |
198 if ( compareRes == 0 ) |
193 data2.TrimAll(); |
199 { |
194 return (CPcsAlgorithm2Utils::MyCompareC(data1, data2)); |
200 if ( idx1 != idx2 ) |
|
201 { |
|
202 // Compare by index position |
|
203 // If idx1 > idx2 and SO is "FN LN" it means for instance that: |
|
204 // Contact1=[FN:"", LN:"Smith"], idx1=2 |
|
205 // Contact2=[FN:"Smith", LN:"Donald"], idx2=1 |
|
206 // Therefore Contact1="Smith" is < than Contact2="Smith Donald" |
|
207 // and the return value of this method has to be < 0 (idx2-idx1) |
|
208 |
|
209 compareRes = idx2 - idx1; |
|
210 } |
|
211 else |
|
212 { |
|
213 // Compare by URI ID as 1st choice and Contact ID as 2nd choice |
|
214 |
|
215 compareRes == ( aObject1.UriId() != aObject2.UriId() ) ? |
|
216 aObject1.UriId() - aObject2.UriId() : aObject1.Id() - aObject2.Id(); |
|
217 } |
|
218 } |
|
219 |
|
220 CleanupStack::PopAndDestroy(&indexOrder2); |
|
221 CleanupStack::PopAndDestroy(&indexOrder1); |
|
222 |
|
223 return compareRes; |
|
224 } |
|
225 |
|
226 // ---------------------------------------------------------------------------- |
|
227 // CPcsAlgorithm2Utils::CompareExact() |
|
228 // |
|
229 // ---------------------------------------------------------------------------- |
|
230 TBool CPcsAlgorithm2Utils::CompareExact(const TDesC& aFirst, const TDesC& aSecond) |
|
231 { |
|
232 return aFirst == aSecond; |
|
233 } |
|
234 |
|
235 // ---------------------------------------------------------------------------- |
|
236 // CPcsAlgorithm2Utils::CompareLength() |
|
237 // |
|
238 // ---------------------------------------------------------------------------- |
|
239 TInt CPcsAlgorithm2Utils::CompareLength(const CPsQuery& aFirst, const CPsQuery& aSecond) |
|
240 { |
|
241 CPsQuery& first = const_cast<CPsQuery&> (aFirst); |
|
242 CPsQuery& second = const_cast<CPsQuery&> (aSecond); |
|
243 |
|
244 return (first.Count() - second.Count()); |
|
245 } |
195 } |
246 |
196 |
247 // ---------------------------------------------------------------------------- |
197 // ---------------------------------------------------------------------------- |
248 // CPcsAlgorithm2Utils::MyTrim() |
198 // CPcsAlgorithm2Utils::MyTrim() |
249 // Trim off all white spaces and special characters |
199 // Trim off all white spaces and special characters |
281 } |
231 } |
282 |
232 |
283 return ETrue; |
233 return ETrue; |
284 } |
234 } |
285 |
235 |
286 // ---------------------------------------------------------------------------- |
|
287 // CPcsAlgorithm1Helper::FilterDataFieldsL() |
|
288 // Constructs a bit pattern using the required/supported data fields |
|
289 // For example, 6, 4 and 27 are supported fields <-- 00000111 |
|
290 // 6 and 4 are required fields <-- 00000011 |
|
291 // Bit pattern returned is 00000011. |
|
292 // ---------------------------------------------------------------------------- |
|
293 TUint8 CPcsAlgorithm2Utils::FilterDataFieldsL(const RArray<TInt>& aRequiredDataFields, |
|
294 const RArray<TInt>& aSupportedDataFields) |
|
295 { |
|
296 TUint8 filteredMatch = 0x0; |
|
297 const TInt supportedDataFieldsCount = aSupportedDataFields.Count(); |
|
298 const TInt requiredDataFieldsCount = aRequiredDataFields.Count(); |
|
299 for ( TInt i = 0; i < supportedDataFieldsCount; i++ ) |
|
300 { |
|
301 for ( TInt j = 0; j < requiredDataFieldsCount; j++ ) |
|
302 { |
|
303 if ( aSupportedDataFields[i] == aRequiredDataFields[j] ) |
|
304 { |
|
305 TUint8 val = 1 << i; |
|
306 filteredMatch |= val; |
|
307 } |
|
308 } |
|
309 } |
|
310 |
|
311 return filteredMatch; |
|
312 } |
|
313 |
|
314 // ---------------------------------------------------------------------------- |
|
315 // CPcsAlgorithm2Utils::AppendMatchToSeqL |
|
316 // ---------------------------------------------------------------------------- |
|
317 void CPcsAlgorithm2Utils::AppendMatchToSeqL( |
|
318 RPointerArray<TDesC>& aMatchSeq, const TDesC& aMatch ) |
|
319 { |
|
320 HBufC* seq = aMatch.AllocLC(); |
|
321 seq->Des().UpperCase(); |
|
322 TIdentityRelation<TDesC> rule(CompareExact); |
|
323 if ( aMatchSeq.Find(seq, rule) == KErrNotFound ) |
|
324 { |
|
325 aMatchSeq.AppendL(seq); |
|
326 CleanupStack::Pop( seq ); |
|
327 } |
|
328 else |
|
329 { |
|
330 CleanupStack::PopAndDestroy( seq ); |
|
331 } |
|
332 } |
|
333 |
|
334 // ---------------------------------------------------------------------------- |
|
335 // CPcsAlgorithm2Utils::MatchesOverlap |
|
336 // Check if two match location items have overlapping indices. |
|
337 // ---------------------------------------------------------------------------- |
|
338 TBool CPcsAlgorithm2Utils::MatchesOverlap( const TPsMatchLocation& aFirst, |
|
339 const TPsMatchLocation& aSecond ) |
|
340 { |
|
341 TBool overlap = EFalse; |
|
342 |
|
343 if ( aFirst.index == aSecond.index ) |
|
344 { |
|
345 overlap = ETrue; |
|
346 } |
|
347 else |
|
348 { |
|
349 // give arguments alias names where first begins before the second |
|
350 TInt firstPos( aFirst.index ); |
|
351 TInt firstLen( aFirst.length ); |
|
352 TInt secondPos( aSecond.index ); |
|
353 if ( firstPos > secondPos ) |
|
354 { |
|
355 firstPos = aSecond.index; |
|
356 firstLen = aSecond.length; |
|
357 secondPos = aFirst.index; |
|
358 } |
|
359 |
|
360 // there is an overlap if the end of the first comes after |
|
361 // beginning of the second |
|
362 if ( firstPos + firstLen > secondPos ) |
|
363 { |
|
364 overlap = ETrue; |
|
365 } |
|
366 } |
|
367 |
|
368 return overlap; |
|
369 } |
|
370 |
|
371 // End of File |
236 // End of File |
372 |
237 |