lafagnosticuifoundation/uigraphicsutils/tulsrc/tulphonenumberutils.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include    <tulphonenumberutils.h>
       
    20 
       
    21 
       
    22 // CONSTANTS
       
    23 // Number matching constants
       
    24 // Note: Space represents all whitespaces in these constants
       
    25 _LIT(KPlainValidChars, "+1234567890()- ./");
       
    26 _LIT(KPlainCharsToParse, "()- ./");
       
    27 _LIT(KContactCardValidChars, "+1234567890()-pw#* ./");
       
    28 _LIT(KContactCardCharsToParse, " ./");
       
    29 _LIT(KPhoneClientValidChars, "+1234567890()-pw#* ./");
       
    30 _LIT(KPhoneClientCharsToParse, "()- ./");
       
    31 _LIT(KSMSNumberValidChars, "+1234567890()- ./*");
       
    32 
       
    33 // DEFINES
       
    34 const TInt KPhoneNoUtilsMinNumbers  = 1;
       
    35 const TInt KPhoneNoUtilsMaxNumbers  = 20;
       
    36 
       
    37 // ---------------------------------------------------------
       
    38 // Phone number parsing methods
       
    39 // ---------------------------------------------------------
       
    40 
       
    41 /**
       
    42 This method is meant for internal use of Phone Parser. 
       
    43 Check if string is a valid phone number
       
    44 @param aNumber Number which will be checked
       
    45 @param aValidChars Characters that are valid for the number.
       
    46           Note: Some chars have special rules. See Address Tokenizer UI specification for more info.
       
    47 @return ETrue if the number was valid, otherwise EFalse.
       
    48 */
       
    49 TBool TulPhoneNumberUtils::IsValidPhoneNumber(const TDesC& aNumber, const TDesC& aValidChars)
       
    50     {
       
    51     TInt TotalNumbers = 0;
       
    52     TInt State = 1;
       
    53     TInt openBrackets = 0;
       
    54     TBool isWhiteSpaceValid = EFalse;
       
    55     // EndStates is a bitfield where each bit value 1 represents
       
    56     // a valid end state.
       
    57     TInt32 EndStates = (1L << 4) | (1L << 7) | (1L << 10) | (1L << 15) | (1L << 17) | 
       
    58         (1L << 18) | (1L << 20) | (1L << 21) | (1L << 22);
       
    59 
       
    60     // Check that if space was valid -> all whitespaces are valid
       
    61     if (aValidChars.Locate(' ') != KErrNotFound)
       
    62         {
       
    63         isWhiteSpaceValid = ETrue;
       
    64         }
       
    65 
       
    66 
       
    67     for(TInt i=0; i < aNumber.Length(); i++)
       
    68         {
       
    69             TChar C = aNumber[i];
       
    70             if (aValidChars.Locate(C) == KErrNotFound)
       
    71                 {
       
    72                 // Space represents all whitespaces in valid chars
       
    73                 if (!(C.IsSpace() && isWhiteSpaceValid))
       
    74                     {
       
    75                     return EFalse;
       
    76                     }
       
    77                 }
       
    78             // White spaces are skipped
       
    79             if (C.IsSpace() || C == '.')
       
    80                 {
       
    81                 continue;
       
    82                 }
       
    83 
       
    84             // Brackets are skipped
       
    85             if (C == '(')
       
    86                 {
       
    87                 if (i == aNumber.Length() - 1)
       
    88                     { // cannot be the last char
       
    89                     return EFalse;
       
    90                     }
       
    91                 openBrackets++;
       
    92                 continue;
       
    93                 }
       
    94             else if (C == ')')
       
    95                 {
       
    96                 if (i == 0)
       
    97                     { // cannot be the first char
       
    98                     return EFalse;
       
    99                     }
       
   100                 openBrackets--;
       
   101                 continue;
       
   102                 }
       
   103 
       
   104             // The numbers are counted
       
   105             if (C.IsDigit())
       
   106                 {
       
   107                 TotalNumbers++;
       
   108                 }
       
   109 
       
   110             // State transitions
       
   111             switch(State)
       
   112                 {
       
   113                 case 1:
       
   114                     if (C == '+')
       
   115                         State = 6;
       
   116                     else if (C.IsDigit())
       
   117                         State = 10;
       
   118                     else if (C == '*' || C == '#')
       
   119                         State = 9;
       
   120                     else
       
   121                         return EFalse;
       
   122                     break;
       
   123                 case 4:
       
   124                     if (C == '-' || C == 'p' || C == 'w' || C=='/')
       
   125                         State = 5;
       
   126                     else if (C == '*' || C == '#')
       
   127                         State = 9;
       
   128                     else if (C.IsDigit())
       
   129                         State = 4;
       
   130                     else
       
   131                         return EFalse;
       
   132                     break;
       
   133                 case 5:
       
   134                     if (C.IsDigit())
       
   135                         State = 4;
       
   136                     else
       
   137                         return EFalse;
       
   138                     break;
       
   139                 case 6:
       
   140                     if (C.IsDigit())
       
   141                         State = 10;
       
   142                     else if (C == '*' || C == '#')
       
   143                         State = 18;
       
   144                     else
       
   145                         return EFalse;
       
   146                     break;
       
   147                 case 9:
       
   148                     if (C.IsDigit())
       
   149                         State = 4;
       
   150                     else if (C != '*' && C != '#')
       
   151                        return EFalse;
       
   152                     break;
       
   153                 case 10:
       
   154                     if (C == '-' || C == 'p' || C == 'w' || C == '/')
       
   155                         State = 11;
       
   156                     else if (C == '*' || C == '#')
       
   157                         State = 18;
       
   158                     else if (!C.IsDigit())
       
   159                         return EFalse;
       
   160                     break;
       
   161                 case 11:
       
   162                     if (C.IsDigit())
       
   163                         State = 10;
       
   164                     else
       
   165                         return EFalse;
       
   166                     break;
       
   167                 case 18:
       
   168                     if (C == '*' || C == '#')
       
   169                         State = 18;
       
   170                     else if (C.IsDigit())
       
   171                         State = 10;
       
   172                     else
       
   173                         return EFalse;
       
   174                     break;
       
   175                 default:
       
   176                 	break;
       
   177                 }
       
   178         }
       
   179 
       
   180     if (TotalNumbers < KPhoneNoUtilsMinNumbers || TotalNumbers > KPhoneNoUtilsMaxNumbers)
       
   181         {
       
   182         return EFalse;
       
   183         }
       
   184 
       
   185     // Check that we left the state machine
       
   186     // in a correct end state.
       
   187     if ((EndStates & (1L << State)) && openBrackets == 0)
       
   188         {
       
   189         return ETrue;
       
   190         }
       
   191     return EFalse;
       
   192 
       
   193     }
       
   194 
       
   195 /**
       
   196 Checks if string is a valid phone number.
       
   197 This method checks if the supplied phone number is a valid phone
       
   198 number of the supplied type.
       
   199 
       
   200 @param aNumber whose validity will be checked.
       
   201 @param aType  is the type of the supplied phone number.
       
   202 @return ETrue if the supplied phone number is a valid number of the 
       
   203 supplied type. Otherwise EFalse.
       
   204 */
       
   205 EXPORT_C TBool TulPhoneNumberUtils::IsValid(const TDesC& aNumber, TPhoneNumberType aType)
       
   206     {
       
   207     TPtrC validChars;
       
   208 
       
   209     switch (aType)
       
   210         {
       
   211         case EPlainPhoneNumber:
       
   212             {
       
   213             validChars.Set(KPlainValidChars);
       
   214             break;
       
   215             }
       
   216         case EContactCardNumber:
       
   217             {
       
   218             validChars.Set(KContactCardValidChars);
       
   219             break;
       
   220             }
       
   221         case EPhoneClientNumber:
       
   222             {
       
   223             validChars.Set(KPhoneClientValidChars);
       
   224             break;
       
   225             }
       
   226 		case ESMSNumber:
       
   227 			{
       
   228 			validChars.Set(KSMSNumberValidChars);
       
   229 			break;
       
   230 			}
       
   231         default:
       
   232             validChars.Set(KNullDesC);
       
   233         }
       
   234     return IsValidPhoneNumber(aNumber, validChars);
       
   235     }
       
   236 
       
   237 /**
       
   238 This method is meant for internal use of Phone Parser.
       
   239 Parses invalid characters from a string
       
   240 @param aNumber Number which will be parsed.
       
   241 @param aInvalidChars Characters that are invalid.
       
   242 */
       
   243 void TulPhoneNumberUtils::ParseInvalidChars(TDes& aNumber, const TDesC& aInvalidChars)
       
   244     {
       
   245     TBool parseWhiteSpaces = EFalse;
       
   246     // If a space needs to be parsed, all whitespaces should be parsed
       
   247     if (aInvalidChars.Locate(' ') != KErrNotFound)
       
   248         {
       
   249         parseWhiteSpaces = ETrue;
       
   250         }
       
   251     for (TInt i = 0; i < aNumber.Length(); i++)
       
   252         {
       
   253         if ((aInvalidChars.Locate(aNumber[i]) != KErrNotFound) ||
       
   254              ((STATIC_CAST(TChar,aNumber[i])).IsSpace() && parseWhiteSpaces))
       
   255             {
       
   256             aNumber.Delete(i,1);
       
   257             i--;
       
   258             }
       
   259         }
       
   260     }
       
   261 
       
   262 /**
       
   263 Parses the supplied phone number. This method removes irrelevant 
       
   264 characters and white spaces from the supplied phone number. Allowed
       
   265 characters are determined by phone number type.
       
   266 
       
   267 @param aNumber will be checked and parsed. After returning contains
       
   268 		the parsed number if the supplied phone number was a valid phone 
       
   269 		number. If the number was not valid no parsing will be done.
       
   270 @param aType is the type of the supplied phone number.
       
   271 @return ETrue if the supplied phone number is a valid number of the
       
   272 supplied type and the parsing succeeds. Otherwise EFalse.
       
   273 */
       
   274 EXPORT_C TBool TulPhoneNumberUtils::Normalize(TDes& aNumber,  TPhoneNumberType aType)
       
   275     {
       
   276     if (!IsValid(aNumber, aType))
       
   277         {
       
   278         return EFalse;
       
   279         }
       
   280     TPtrC charsToParse;
       
   281 
       
   282     switch (aType)
       
   283         {
       
   284         case EPlainPhoneNumber:
       
   285 		case ESMSNumber:
       
   286             {
       
   287             charsToParse.Set(KPlainCharsToParse);
       
   288             break;
       
   289             }
       
   290         case EContactCardNumber:
       
   291             {
       
   292             charsToParse.Set(KContactCardCharsToParse);
       
   293             break;
       
   294             }
       
   295         case EPhoneClientNumber:
       
   296             {
       
   297             charsToParse.Set(KPhoneClientCharsToParse);
       
   298             break;
       
   299             }
       
   300         }
       
   301     ParseInvalidChars(aNumber, charsToParse);
       
   302     
       
   303     return ETrue;
       
   304     }
       
   305 
       
   306 //  End of File