predictivesearch/PcsAlgorithm/Algorithm1/src/CPcsAlgorithm1Utils.cpp
branchRCL_3
changeset 21 9da50d567e3c
parent 20 f4a778e096c2
equal deleted inserted replaced
20:f4a778e096c2 21:9da50d567e3c
    21 #include "CPsData.h"
    21 #include "CPsData.h"
    22 #include "CPcsDefs.h"
    22 #include "CPcsDefs.h"
    23 #include "CPcsCache.h"
    23 #include "CPcsCache.h"
    24 #include "CPsQuery.h"
    24 #include "CPsQuery.h"
    25 #include "CPsQueryItem.h"
    25 #include "CPsQueryItem.h"
       
    26 #include "CPcsDebug.h"
    26 
    27 
    27 #include <collate.h>
    28 #include <collate.h>
    28 
    29 
    29 // CONSTANTS
    30 // CONSTANTS
    30 _LIT(KSpace, ' ');
    31 _LIT(KSpace, ' ');
   210 
   211 
   211 // ----------------------------------------------------------------------------
   212 // ----------------------------------------------------------------------------
   212 // CPcsAlgorithm1Utils::CompareDataBySortOrderL()
   213 // CPcsAlgorithm1Utils::CompareDataBySortOrderL()
   213 // TLinearOrder rule for comparison of data objects
   214 // TLinearOrder rule for comparison of data objects
   214 // ----------------------------------------------------------------------------
   215 // ----------------------------------------------------------------------------
   215 TInt CPcsAlgorithm1Utils::CompareDataBySortOrderL(const CPsData& aObject1, 
   216 TInt CPcsAlgorithm1Utils::CompareDataBySortOrderL(const CPsData& aObject1,
   216                                                   const CPsData& aObject2)
   217                                                   const CPsData& aObject2)
   217     {
   218     {
   218     TInt compareRes(0);
   219     TInt compareRes = 0;
   219     
   220 
   220     if( CPsData::CompareById(aObject1, aObject2) )
   221     if( CPsData::CompareById(aObject1, aObject2) )
   221         {
   222         {
   222         return compareRes;
   223         return compareRes;
   223         }
   224         }
   224     
   225 
   225     // Fetch the cache list stored in TLS to recover the sort order
   226     // Fetch the cache list stored in TLS to recover the sort order
   226     typedef RPointerArray<CPcsCache> PTR;
   227     typedef RPointerArray<CPcsCache> PTR;
   227     PTR* pcsCache = static_cast<PTR*>(Dll::Tls());
   228     PTR* pcsCache = static_cast<PTR*>(Dll::Tls());
   228     User::LeaveIfNull(pcsCache);
   229     User::LeaveIfNull(pcsCache);
   229     
   230 
   230 	CPcsCache* cache1 = (*pcsCache)[aObject1.UriId()];
   231     CPcsCache* cache1 = (*pcsCache)[aObject1.UriId()];
   231     CPcsCache* cache2 = (*pcsCache)[aObject2.UriId()];
   232     CPcsCache* cache2 = (*pcsCache)[aObject2.UriId()];
   232 	RArray<TInt> indexOrder1;
   233     RArray<TInt> indexOrder1;
   233     RArray<TInt> indexOrder2;
   234     RArray<TInt> indexOrder2;
   234 	  
   235 
   235     // Get the index order based on sort order from the cache
   236     // Get the index order based on sort order from the cache
   236 	cache1->GetIndexOrder(indexOrder1);
   237     cache1->GetIndexOrder(indexOrder1);
   237 	CleanupClosePushL(indexOrder1);
   238     CleanupClosePushL(indexOrder1);
   238 	cache2->GetIndexOrder(indexOrder2);
   239     cache2->GetIndexOrder(indexOrder2);
   239 	CleanupClosePushL(indexOrder2);
   240     CleanupClosePushL(indexOrder2);
   240 
   241 
   241 	TInt idx2 = 0;
   242     // Check if Sort Order is identical (it must be for same cache)
   242 	for(TInt idx1 = 0; 
   243     TBool sameIndexOrder = ETrue;
   243         idx1 < indexOrder1.Count() && idx2 < indexOrder2.Count() && compareRes == 0; 
   244     if ( indexOrder1.Count() != indexOrder2.Count() )
   244         idx1++)
   245         {
   245         {
   246         sameIndexOrder = EFalse;
       
   247         }
       
   248     else
       
   249         {
       
   250         for ( TInt i = 0; i < indexOrder1.Count(); i++ )
       
   251             {
       
   252             if (indexOrder1[i] != indexOrder2[i])
       
   253                 {
       
   254                 sameIndexOrder = EFalse;
       
   255                 break;
       
   256                 }
       
   257             }
       
   258         }
       
   259 
       
   260     // Sort Orders among different caches should be the same, anyway
       
   261     // if caches and SO are different we compare by cache URI index
       
   262     if (!sameIndexOrder)
       
   263         {
       
   264         compareRes = aObject1.UriId() - aObject2.UriId();
       
   265 
       
   266         CleanupStack::PopAndDestroy(&indexOrder2);
       
   267         CleanupStack::PopAndDestroy(&indexOrder1);
       
   268         return compareRes;
       
   269         }
       
   270 
       
   271     // The comparison between contacts data is done for the sort order
       
   272     // fields skipping the ones that are empty
       
   273     TInt indexCount = indexOrder1.Count();
       
   274     TInt idx1 = 0;
       
   275     TInt idx2 = 0;
       
   276     while ( compareRes == 0 && idx1 < indexCount && idx2 < indexCount )
       
   277         {
       
   278         // Get contact field of 1st contact
   246         TInt object1Idx = indexOrder1[idx1];
   279         TInt object1Idx = indexOrder1[idx1];
   247         HBufC* strCompare1 = aObject1.Data(object1Idx)->Des().AllocLC();
   280         HBufC* strCompare1 = aObject1.Data(object1Idx)->Des().AllocLC();
   248         
   281         TPtr strCompare1Ptr( strCompare1->Des() );
   249         if ( object1Idx < aObject1.DataElementCount() 
   282         CPcsAlgorithm1Utils::MyTrim( strCompare1Ptr );
   250              && aObject1.Data(object1Idx)
   283 
   251              && strCompare1->Length() )
   284         // Get contact field of 2nd contact
   252             {
   285         TInt object2Idx = indexOrder2[idx2];
   253             strCompare1->Des().TrimAll();
   286         HBufC* strCompare2 = aObject2.Data(object2Idx)->Des().AllocLC();
   254             
   287         TPtr strCompare2Ptr( strCompare2->Des() );
   255             for(; idx2 < indexOrder2.Count(); idx2++)
   288         CPcsAlgorithm1Utils::MyTrim( strCompare2Ptr );
   256                 {
   289 
   257                 TInt object2Idx = indexOrder2[idx2];
   290         if ( strCompare1->Length() > 0 && strCompare2->Length() > 0 )
   258                 
   291             {
   259                 HBufC* strCompare2 = aObject2.Data(object2Idx)->Des().AllocLC();
   292             compareRes = CPcsAlgorithm1Utils::MyCompareC(*strCompare1, *strCompare2);
   260                 
   293             idx1++;
   261                 if( strCompare2->Length() )
   294             idx2++;
   262                     {
   295             }
   263                     strCompare2->Des().TrimAll();
   296         else // Increment only the index of the contact with empty field
   264                     
   297             {
   265                     compareRes = CPcsAlgorithm1Utils::MyCompareC(*strCompare1, *strCompare2);
   298             if ( strCompare1->Length() == 0 )
   266                     
   299                 idx1++;
   267                     CleanupStack::PopAndDestroy(strCompare2);
   300             if ( strCompare2->Length() == 0 )
   268                     
   301                 idx2++;
   269                     if( compareRes == 0 )
   302             }
   270                         {
   303 
   271                         idx2++;
   304         CleanupStack::PopAndDestroy(strCompare2);
   272                         }
       
   273                     break;
       
   274                     }
       
   275                 CleanupStack::PopAndDestroy(strCompare2);
       
   276                 }
       
   277             }
       
   278         CleanupStack::PopAndDestroy(strCompare1);
   305         CleanupStack::PopAndDestroy(strCompare1);
   279         }
   306         }
   280   
   307 
   281 	CleanupStack::PopAndDestroy(&indexOrder2);
   308     // We do not return that contacts are equal by SO
       
   309     if ( compareRes == 0 )
       
   310         {
       
   311         if ( idx1 != idx2 )
       
   312             {
       
   313             // Compare by index position
       
   314             // If idx1 > idx2 and SO is "FN LN" it means for instance that:
       
   315             //     Contact1=[FN:"",      LN:"Smith"],  idx1=2
       
   316             //     Contact2=[FN:"Smith", LN:"Donald"], idx2=1
       
   317             // Therefore Contact1="Smith" is < than Contact2="Smith Donald"
       
   318             // and the return value of this method has to be < 0 (idx2-idx1)
       
   319 
       
   320             compareRes = idx2 - idx1;
       
   321             }
       
   322         else
       
   323             {
       
   324             // Compare by URI ID as 1st choice and Contact ID as 2nd choice
       
   325 
       
   326             compareRes == ( aObject1.UriId() != aObject2.UriId() ) ?
       
   327                 aObject1.UriId() - aObject2.UriId() : aObject1.Id() - aObject2.Id();
       
   328             }
       
   329         }
       
   330 
       
   331     CleanupStack::PopAndDestroy(&indexOrder2);
   282     CleanupStack::PopAndDestroy(&indexOrder1);
   332     CleanupStack::PopAndDestroy(&indexOrder1);
   283 
   333 
   284     return compareRes;
   334     return compareRes;
   285     }
   335     }
   286 
   336