plugins/contacts/symbiansim/src/cntsymbiansimengine.cpp
changeset 5 603d3f8b6302
parent 0 876b1a06bc25
equal deleted inserted replaced
3:e4ebb16b39ea 5:603d3f8b6302
   527         QContactDetailFilter f(filter);
   527         QContactDetailFilter f(filter);
   528         if (f.detailDefinitionName() == QContactPhoneNumber::DefinitionName && 
   528         if (f.detailDefinitionName() == QContactPhoneNumber::DefinitionName && 
   529             f.detailFieldName() == QContactPhoneNumber::FieldNumber &&
   529             f.detailFieldName() == QContactPhoneNumber::FieldNumber &&
   530             f.matchFlags() == QContactFilter::MatchPhoneNumber) 
   530             f.matchFlags() == QContactFilter::MatchPhoneNumber) 
   531         {
   531         {
   532             QString matchNumber = f.value().toString().right(d->m_phoneNumberMatchLen);
       
   533             QList<QContactPhoneNumber> pns = contact.details<QContactPhoneNumber>();
   532             QList<QContactPhoneNumber> pns = contact.details<QContactPhoneNumber>();
   534             foreach (QContactPhoneNumber pn, pns) {
   533             foreach (QContactPhoneNumber pn, pns) {
   535                 QString number = pn.number().right(d->m_phoneNumberMatchLen);
   534                 // Best matching enabled
   536                 if (number == matchNumber)
   535                 if(d->m_phoneNumberMatchLen == 0) {
   537                     return true;
   536                     bool bestMatchFound(false);
       
   537                     QString matchingNumber = f.value().toString();
       
   538                     QString numberToMatch = pn.number();
       
   539                     TRAP_IGNORE(
       
   540                             bestMatchFound = CntSymbianSimPhoneNumberMatching::isBestMatchL(numberToMatch,matchingNumber);
       
   541                     )
       
   542                     if (bestMatchFound)
       
   543                         return true;
       
   544                 }
       
   545                 else {
       
   546                     // Default matching
       
   547                     QString matchNumber = f.value().toString().right(d->m_phoneNumberMatchLen);
       
   548                     QString number = pn.number().right(d->m_phoneNumberMatchLen);
       
   549                     if (number == matchNumber)
       
   550                         return true;
       
   551                 }
   538             }
   552             }
   539             return false;
   553             return false;
   540         }
   554         }
   541     }
   555     }
   542     return QContactManagerEngine::testFilter(filter, contact);
   556     return QContactManagerEngine::testFilter(filter, contact);
       
   557 }
       
   558 
       
   559 /*!
       
   560   Returns whether the supplied \a phonenumber is the best matching number.
       
   561  */
       
   562 TBool CntSymbianSimPhoneNumberMatching::isBestMatchL(const QString& numberToMatch, const QString& matchingNumber)
       
   563 {
       
   564     bool bestMatchFound(false);
       
   565     TPtrC numberPtr(reinterpret_cast<const TUint16*>(numberToMatch.utf16()));
       
   566     TPtrC matchNumberPtr(reinterpret_cast<const TUint16*>(matchingNumber.utf16()));
       
   567     
       
   568     if (CntSymbianSimPhoneNumberMatching::validateBestMatchingRulesL(numberPtr,matchNumberPtr)) {
       
   569         bestMatchFound = true;
       
   570     }
       
   571     return bestMatchFound;
   543 }
   572 }
   544 
   573 
   545 /*!
   574 /*!
   546  * Executes an asynchronous request so that it will appear synchronous. This is
   575  * Executes an asynchronous request so that it will appear synchronous. This is
   547  * used internally in all synchronous functions. This way we only need to 
   576  * used internally in all synchronous functions. This way we only need to 
   591     CleanupStack::PushL(repository);
   620     CleanupStack::PushL(repository);
   592     User::LeaveIfError(repository->Get(KTelMatchDigits, matchLength));
   621     User::LeaveIfError(repository->Get(KTelMatchDigits, matchLength));
   593     CleanupStack::PopAndDestroy(repository);
   622     CleanupStack::PopAndDestroy(repository);
   594 }
   623 }
   595 
   624 
       
   625 /*!
       
   626   Validates the supplied \a phonenumber against best matching rules.
       
   627  */
       
   628 TBool CntSymbianSimPhoneNumberMatching::validateBestMatchingRulesL(const TDesC& phoneNumber, const TDesC& matchNumber)
       
   629     {
       
   630     RBuf numberA;
       
   631     numberA.CleanupClosePushL();
       
   632     numberA.CreateL(matchNumber);
       
   633     TNumberType numberAType = (TNumberType) CntSymbianSimPhoneNumberMatching::formatAndCheckNumberType(numberA);
       
   634     RBuf numberB;
       
   635     numberB.CleanupClosePushL();
       
   636     numberB.CreateL(phoneNumber);
       
   637     TNumberType numberBType = (TNumberType) CntSymbianSimPhoneNumberMatching::formatAndCheckNumberType(numberB);
       
   638 
       
   639     TBool match = (!numberB.Compare(numberA) ||
       
   640                     CntSymbianSimPhoneNumberMatching::checkBestMatchingRules(numberA, numberAType, numberB, numberBType) ||
       
   641                     CntSymbianSimPhoneNumberMatching::checkBestMatchingRules(numberB, numberBType, numberA, numberAType));
       
   642     
       
   643     // cleanup
       
   644     CleanupStack::PopAndDestroy(2);
       
   645     return match;
       
   646     }
       
   647 
       
   648 /*!
       
   649   Removes non-digit chars except plus form the beginning.
       
   650   Checks if number matches to one of defined types.
       
   651  */
       
   652 TInt CntSymbianSimPhoneNumberMatching::formatAndCheckNumberType(TDes& number)
       
   653     {
       
   654     _LIT( KOneZeroPattern, "0*" );
       
   655     _LIT( KTwoZerosPattern, "00*" );
       
   656     _LIT( KPlusPattern, "+*" );
       
   657     const TChar KPlus = TChar('+');
       
   658     const TChar KZero = TChar('0');
       
   659     const TChar KAsterisk = TChar('*');
       
   660     const TChar KHash = TChar('#');
       
   661     
       
   662     for( TInt pos = 0; pos < number.Length(); ++pos ) {
       
   663         TChar chr = number[pos];
       
   664         if ( !chr.IsDigit() && !( pos == 0 && chr == KPlus  )
       
   665                 && !( chr == KAsterisk ) && !( chr == KHash ) ) {
       
   666             number.Delete( pos, 1 );
       
   667             --pos;
       
   668         }
       
   669     }
       
   670     
       
   671     TInt format;
       
   672     
       
   673     if (!number.Match(KTwoZerosPattern) && number.Length() > 2 && number[2] != KZero) {
       
   674         format = ETwoZeros;
       
   675     }
       
   676     else if (!number.Match(KOneZeroPattern)&& number.Length() > 1 && number[1] != KZero) {
       
   677         format = EOneZero;
       
   678     }
       
   679     else if (!number.Match(KPlusPattern) && number.Length() > 1 && number[1] != KZero) {
       
   680         format = EPlus;
       
   681     }
       
   682     else if (number.Length() > 0 && number[0] != KZero && ( ( TChar ) number[0] ).IsDigit()) {
       
   683         format = EDigit;
       
   684     }
       
   685     else {
       
   686         format = EUnknown;
       
   687     }
       
   688 
       
   689     return format;
       
   690     }
       
   691 
       
   692 TBool CntSymbianSimPhoneNumberMatching::checkBestMatchingRules(
       
   693         const TDesC& numberA, TNumberType numberAType,
       
   694         const TDesC& numberB, TNumberType numberBType  )
       
   695     {
       
   696     TBool result = EFalse;
       
   697     
       
   698     // Rules for matching not identical numbers
       
   699     // Rules details are presented in Best_Number_Matching_Algorithm_Description.doc
       
   700     
       
   701     // rule International-International 1
       
   702     if (!result && numberAType == EPlus && numberBType == ETwoZeros) {
       
   703         TPtrC numberAPtr = numberA.Right(numberA.Length() - 1);
       
   704         TPtrC numberBPtr = numberB.Right(numberB.Length() - 2);
       
   705         result = !(numberAPtr.Compare(numberBPtr));
       
   706         if (result) {
       
   707             return result;
       
   708         }
       
   709     }
       
   710 
       
   711     // rule International-International 2
       
   712     if (numberAType == EPlus && numberBType == EDigit) {
       
   713         TPtrC numberAPtr = numberA.Right( numberA.Length() - 1 );
       
   714         if (numberAPtr.Length() < numberB.Length()) {
       
   715             TPtrC numberBPtr = numberB.Right( numberAPtr.Length() );
       
   716             result = !(numberAPtr.Compare(numberBPtr));
       
   717             if (result) {
       
   718                 return result;
       
   719             }
       
   720         }
       
   721     }
       
   722 
       
   723     // rule International-International 3
       
   724     if (numberAType == ETwoZeros && numberBType == EDigit) {
       
   725         TPtrC numberAPtr = numberA.Right(numberA.Length() - 2);
       
   726         if (numberAPtr.Length() < numberB.Length()) {
       
   727             TPtrC numberBPtr = numberB.Right(numberAPtr.Length());
       
   728             result = !(numberAPtr.Compare(numberBPtr));
       
   729             if (result) {
       
   730                 return result;
       
   731             }
       
   732         }
       
   733     }
       
   734 
       
   735     // rule International-Operator 1
       
   736     if (numberAType == EOneZero && numberBType == EPlus
       
   737             || numberAType == EDigit && numberBType == EPlus) {
       
   738         TPtrC numberAPtr;
       
   739         if (numberAType == EOneZero) {
       
   740             numberAPtr.Set(numberA.Right(numberA.Length() - 1));
       
   741         }
       
   742         else {
       
   743             numberAPtr.Set(numberA);
       
   744         }
       
   745         if (numberAPtr.Length() < numberB.Length() - 1) {
       
   746             TPtrC numberBPtr = numberB.Right(numberAPtr.Length());
       
   747             result = !(numberAPtr.Compare(numberBPtr));
       
   748             if (result) {
       
   749                 return result;
       
   750             }
       
   751         }
       
   752     }
       
   753 
       
   754     // rule International-Operator 2
       
   755     if (numberAType == EOneZero && numberBType == ETwoZeros
       
   756             || numberAType == EDigit && numberBType == ETwoZeros) {
       
   757         TPtrC numberAPtr;
       
   758         if (numberAType == EOneZero) {
       
   759             numberAPtr.Set(numberA.Right(numberA.Length() - 1));
       
   760         }
       
   761         else {
       
   762             numberAPtr.Set(numberA);
       
   763         }
       
   764         if (numberAPtr.Length() < numberB.Length() - 2) {
       
   765             TPtrC numberBPtr = numberB.Right(numberAPtr.Length());
       
   766             result = !(numberAPtr.Compare(numberBPtr));
       
   767             if (result) {
       
   768                 return result;
       
   769             }
       
   770         }
       
   771     }
       
   772 
       
   773     // rule International-Operator 3
       
   774     if (numberAType == EOneZero && numberBType == EDigit
       
   775             || numberAType == EDigit && numberBType == EDigit) {
       
   776         TPtrC numberAPtr;
       
   777         if (numberAType == EOneZero) {
       
   778             numberAPtr.Set(numberA.Right( numberA.Length() - 1));
       
   779         }
       
   780         else {
       
   781             numberAPtr.Set(numberA);
       
   782         }
       
   783         if (numberAPtr.Length() < numberB.Length()) {
       
   784             TPtrC numberBPtr = numberB.Right(numberAPtr.Length());
       
   785             result = !(numberAPtr.Compare(numberBPtr));
       
   786             if (result) {
       
   787                 return result;
       
   788             }
       
   789         }
       
   790     }
       
   791 
       
   792     // rule Operator-Operator 1
       
   793     if (numberAType == EOneZero && numberBType == EDigit) {
       
   794         TPtrC numberAPtr = numberA.Right(numberA.Length() - 1);
       
   795         result = !(numberAPtr.Compare(numberB));
       
   796         if (result) {
       
   797             return result;
       
   798         }
       
   799     }
       
   800     
       
   801     // rule North America Numbering Plan 1
       
   802     if (numberAType == EDigit && numberBType == EPlus) {
       
   803         TPtrC numberBPtr = numberB.Right(numberB.Length() - 1);
       
   804         result = !(numberA.Compare(numberBPtr));
       
   805         if (result) {
       
   806             return result;
       
   807         }
       
   808     }
       
   809 
       
   810     // More exceptional acceptance rules can be added here
       
   811     // Keep rules updated in the document Best_Number_Matching_Algorithm_Description.doc
       
   812 
       
   813     return result;
       
   814     }
       
   815 
   596 QContactManagerEngine* CntSymbianSimFactory::engine(const QMap<QString, QString>& parameters, QContactManager::Error* error)
   816 QContactManagerEngine* CntSymbianSimFactory::engine(const QMap<QString, QString>& parameters, QContactManager::Error* error)
   597 {
   817 {
   598     CntSymbianSimEngine *engine = new CntSymbianSimEngine(parameters, error);
   818     CntSymbianSimEngine *engine = new CntSymbianSimEngine(parameters, error);
   599     if(*error != QContactManager::NoError) {
   819     if(*error != QContactManager::NoError) {
   600         delete engine;
   820         delete engine;