wvuing/Utils/CAUtils.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2004-2006 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:  Utils for IM modules.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CAUtils.h"
       
    20 #include "CCAStorageManagerFactory.h"
       
    21 #include "MCAStoredContacts.h"
       
    22 #include "ChatDebugPrint.h"
       
    23 #include "impsbuilddefinitions.h"
       
    24 
       
    25 #include <EscapeUtils.h>
       
    26 #include <collate.h>
       
    27 
       
    28 // needed to skip prefixes in domain-neutral comparison (TUint version)
       
    29 const TUint KColonUInt( ':' );
       
    30 
       
    31 // needed to skip domains in domain-neutral comparison (TUint version)
       
    32 const TUint KAtUInt( '@' );
       
    33 // general colon needed in various places
       
    34 _LIT( KColon, ":" );
       
    35 
       
    36 // general slash needed in various places
       
    37 _LIT( KSlash, "/" );
       
    38 
       
    39 // needed to skip domains in domain-neutral comparison
       
    40 _LIT( KAt, "@" );
       
    41 
       
    42 // "test character identity and accents, ignore case"
       
    43 const TInt KCollationLevel = 1;
       
    44 
       
    45 // max number to store any values
       
    46 const TInt KMAX_NUMBER = 12;
       
    47 
       
    48 // max number to fit
       
    49 const TInt KMAX_LIMIT = 255;
       
    50 
       
    51 // max number base
       
    52 const TInt KMAX_NUMBERBASE = 10;
       
    53 
       
    54 // some character value constants
       
    55 //const TUint K7LSBMask       = 0x7f     // bitmask for 7 lsb bits
       
    56 const TUint K8BitMask       = 0xff;     // full bitmask
       
    57 //const TUint KCharCodeZero   = 0x30     // '0'
       
    58 //const TUint KCharCodeSmallZ = 0x7a     // 'z'
       
    59 //const TUint KCharCodeSpace  = 0x20     // ' '
       
    60 const TUint KCharToArea     = 0x030;
       
    61 
       
    62 // Unused areas (2) in ISO 8859-1 specification
       
    63 //const TUint KUnused8859start1 = 0x00
       
    64 const TUint KUnused8859end1 = 0x1F;
       
    65 const TUint KUnused8859start2 = 0x7F;
       
    66 const TUint KUnused8859end2 = 0x9F;
       
    67 
       
    68 // forbidden characters that cannot appear in Wireless Village Ids
       
    69 _LIT( KWVForbiddenCharacters, "/@+ \t:" );
       
    70 
       
    71 /**
       
    72  * Constants to use in validation.
       
    73  *
       
    74  */
       
    75 _LIT( KCUImpsId_WhiteSpace, " " );
       
    76 _LIT( KCUImpsId_At, "@" );
       
    77 _LIT( KCUImpsId_Dot, "." );
       
    78 _LIT( KCUImpsId_TwoDots, ".." );
       
    79 _LIT( KCUImpsId_Slash, "/" );
       
    80 _LIT( KCUImpsId_Plus, "+" );
       
    81 _LIT( KCUImpsId_Tabulator, "\t" );
       
    82 _LIT( KCUImpsId_WVPrefix, "wv:" );
       
    83 
       
    84 _LIT( KCUImpsId_AtEnc, "%40" );
       
    85 _LIT( KCUImpsId_SlashEnc, "%2F" );
       
    86 _LIT( KCUImpsId_PlusEnc, "%2B" );
       
    87 _LIT( KCUImpsId_TabulatorEnc, "%09" );
       
    88 _LIT( KCUImpsId_WhiteSpaceEnc, "%20" );
       
    89 
       
    90 // length of "wv:" prefix
       
    91 const TInt KCUImpsId_WVPrefixLength = 3;
       
    92 
       
    93 // maximum length of user id
       
    94 const TInt KServerWVUserIdMaxLength = 50;
       
    95 
       
    96 // defines how far we are going to search for the protocol part in user id
       
    97 const TInt KMaxLengthSearchProtPart = 4;
       
    98 
       
    99 // maximum numerical value to append to generated WVID.
       
   100 const TInt KMaxAppendNumber = 9999;
       
   101 
       
   102 // -----------------------------------------------------------------------------
       
   103 // CAUtils::NeutralCompare
       
   104 // -----------------------------------------------------------------------------
       
   105 //
       
   106 TInt CAUtils::NeutralCompare( const TDesC& aId1,
       
   107                               const TDesC& aId2, TBool aDomainNeutral )
       
   108     {
       
   109     // points to user part of id
       
   110     TPtrC ptrId1( aId1 );
       
   111     TPtrC ptrId2( aId2 );
       
   112 
       
   113     // Reduce looking for protocol part only to beginning of the WVID and
       
   114     // skip protocol part ("anything:") in the beginning of the WVID
       
   115     TInt colonPos1 = aId1.Left( KMaxLengthSearchProtPart ).Locate( KColonUInt );
       
   116 
       
   117     // first id
       
   118     if ( ( KErrNotFound != colonPos1 ) && ( aId1.Length() - 1 != colonPos1 ) )
       
   119         {
       
   120         // contains ":", and it is not the last char
       
   121         ptrId1.Set( aId1.Mid( colonPos1 + 1 ) );
       
   122         }
       
   123 
       
   124     TInt colonPos2 = aId2.Left( KMaxLengthSearchProtPart ).Locate( KColonUInt );
       
   125 
       
   126     // second id
       
   127     if ( ( KErrNotFound != colonPos2 ) && ( aId2.Length() - 1 != colonPos2 ) )
       
   128         {
       
   129         // contains ":", and it is not the last char
       
   130         ptrId2.Set( aId2.Mid( colonPos2 + 1 ) );
       
   131         }
       
   132 
       
   133     // find out if we have domains in the ids
       
   134     TInt domainPos1( ptrId1.Locate( KAtUInt ) );
       
   135     TInt domainPos2( ptrId2.Locate( KAtUInt ) );
       
   136 
       
   137     TBool domainIn1( KErrNotFound != domainPos1 );
       
   138     TBool domainIn2( KErrNotFound != domainPos2 );
       
   139 
       
   140     // points to domains in the neutral id
       
   141     TPtrC ptrDom1( KNullDesC );
       
   142     TPtrC ptrDom2( KNullDesC );
       
   143 
       
   144     // points to user parts in the neutral id
       
   145     TPtrC ptrUid1( ptrId1 );
       
   146     TPtrC ptrUid2( ptrId2 );
       
   147 
       
   148     // separate user id parts and domain parts
       
   149     if ( domainIn1 )
       
   150         {
       
   151         ptrDom1.Set( ptrId1.Mid( domainPos1 + 1 ) );
       
   152         ptrUid1.Set( ptrId1.Mid( 0, domainPos1 ) );
       
   153         }
       
   154 
       
   155     if ( domainIn2 )
       
   156         {
       
   157         ptrDom2.Set( ptrId2.Mid( domainPos2 + 1 ) );
       
   158         ptrUid2.Set( ptrId2.Mid( 0, domainPos2 ) );
       
   159         }
       
   160 
       
   161     // Create custom collation method to ignore punctuations
       
   162     // index 0 gets the default method
       
   163     TCollationMethod collation =
       
   164         *Mem::CollationMethodByIndex( 0 );
       
   165     collation.iFlags |= TCollationMethod::EIgnoreNone;
       
   166 
       
   167     // domains are compared only when it is really needed
       
   168     // check if userid part is the same in both ids
       
   169     TInt idResult = ptrUid1.CompareC( ptrUid2, KCollationLevel, &collation );
       
   170 
       
   171     if ( idResult != 0 )
       
   172         {
       
   173         return idResult;
       
   174         }
       
   175 
       
   176     // id part is same, we have to compare domain
       
   177 
       
   178     // If domain comparison is neutral and one id is without domain
       
   179     // -> Domains are same. Other situation domainResult stays valid.
       
   180     if ( aDomainNeutral && ( domainIn1 ^ domainIn2 ) )
       
   181         {
       
   182         return 0;
       
   183         }
       
   184     else
       
   185         {
       
   186         return ptrDom1.CompareC( ptrDom2, KCollationLevel, &collation );
       
   187         }
       
   188     }
       
   189 
       
   190 // -----------------------------------------------------------------------------
       
   191 // CAUtils::DisplayId
       
   192 // -----------------------------------------------------------------------------
       
   193 //
       
   194 TPtrC CAUtils::DisplayId( const TDesC& aId, TBool aListHiding )
       
   195     {
       
   196     TPtrC ret( aId );
       
   197 
       
   198     MCAStoredContacts* contacts = NULL;
       
   199     TRAPD( err, contacts = CCAStorageManagerFactory::ContactListInterfaceL() );
       
   200     if ( err != KErrNone || !contacts )
       
   201         {
       
   202         // some error, don't modify
       
   203         CHAT_DP_FUNC_DP( "DisplayId", "Got some error, not hiding" );
       
   204         return ret;
       
   205         }
       
   206 
       
   207     // if we've branded the feature out, don't modify anything
       
   208     // UI CR : 101-39728:  Check for prefix hiding or Wv hiding.
       
   209     if ( contacts->WVHiding() || contacts->WVHidingPrefixOnly() )
       
   210         {
       
   211         // locate ":" for userid, groupid.
       
   212         // locate "/" for list id.
       
   213         TInt pos = aId.FindC( aListHiding ? KSlash : KColon );
       
   214 
       
   215         if ( ( pos != KErrNotFound ) && ( pos != aId.Length() - 1 ) )
       
   216             {
       
   217             // contains the special character, and it is not the last char
       
   218             // remove everything before the special char (including the char)
       
   219             ret.Set( aId.Mid( pos + 1 ) );
       
   220             }
       
   221         if ( contacts->WVHiding() || aListHiding )
       
   222             {
       
   223             // remove also the domain part
       
   224             TInt domainPos = ret.FindC( KAt );
       
   225             if ( ( domainPos != KErrNotFound ) && ( domainPos != 0 ) )
       
   226                 {
       
   227                 ret.Set( ret.Mid( 0, domainPos ) );
       
   228                 }
       
   229 
       
   230             }
       
   231         }
       
   232 
       
   233     return ret;
       
   234     }
       
   235 // -----------------------------------------------------------------------------
       
   236 // CAUtils::GenerateIdLC
       
   237 // -----------------------------------------------------------------------------
       
   238 //
       
   239 HBufC* CAUtils::GenerateIdLC( const TDesC& aId, TInt aNum )
       
   240     {
       
   241     // copy ID
       
   242     HBufC* result = HBufC::NewLC( KServerWVUserIdMaxLength );
       
   243     TPtr resultPtr( result->Des() );
       
   244     resultPtr.Copy( aId );
       
   245 
       
   246     TInt len( resultPtr.Length() );
       
   247 
       
   248     // Start from end of data
       
   249     for ( TInt i( len - 1 ); i >= 0; --i )
       
   250         {
       
   251         // Do quick and dirty UNICODE to ISO-8859-1 conversion
       
   252         // and modify all non-ISO-8859-1 characters
       
   253         // to be in valid ranges
       
   254         const TInt& currentChar = resultPtr[ i ];
       
   255         TUint ch = currentChar & K8BitMask;
       
   256 
       
   257         // is ch in first unused area
       
   258         if ( ch <= KUnused8859end1 )
       
   259             {
       
   260             ch += KUnused8859end1 + 1;
       
   261             }
       
   262 
       
   263         // is ch in second unused area
       
   264         if ( ch >= KUnused8859start2 && ch <= KUnused8859end2 )
       
   265             {
       
   266             TInt difference = ch - KUnused8859start2;
       
   267             ch = KUnused8859end2 + difference + 1;
       
   268             }
       
   269 
       
   270         TChar isoFixedChar = TChar( ch );
       
   271         // put it into the string
       
   272         HBufC* isoFixed = HBufC::NewLC( 1 );
       
   273         isoFixed->Des().Append( isoFixedChar );
       
   274 
       
   275         resultPtr.Replace( i, 1, *isoFixed );
       
   276         CleanupStack::PopAndDestroy( isoFixed );
       
   277 
       
   278         // now all the specials get removed
       
   279         TPtrC c = resultPtr.Mid( i, 1 );  // next character
       
   280         TInt position = KWVForbiddenCharacters().FindF( c );
       
   281 
       
   282         if ( position != KErrNotFound )
       
   283             {
       
   284             // the current character is a FORBIDDEN CHARACTER,
       
   285             // remove it
       
   286             resultPtr.Delete( i, 1 );
       
   287             }
       
   288         }
       
   289 
       
   290     CHAT_DP( D_CHAT_LIT( "CAUtils::GenerateIdLC conversion '%S' -> '%S'" ), &aId, &resultPtr );
       
   291 
       
   292     // "Append" number
       
   293     if ( aNum > 0 && aNum <= KMaxAppendNumber )
       
   294         {
       
   295         TBuf<KMAX_NUMBER> number; // 12, enough space to store a very large number
       
   296         number.AppendNum( aNum );
       
   297 
       
   298         TInt numLength = number.Length();
       
   299         TInt resultLength = resultPtr.Length();
       
   300         if ( numLength + resultLength > KServerWVUserIdMaxLength )
       
   301             {
       
   302             // can't append directly because we would exceed the space.
       
   303             // use replace instead
       
   304             TInt usableSpace = KServerWVUserIdMaxLength - resultLength;
       
   305             TInt startPos = resultLength - numLength + usableSpace;
       
   306             TInt replaceAmount = numLength - usableSpace;
       
   307 
       
   308             resultPtr.Replace( startPos, replaceAmount, number );
       
   309             }
       
   310         else
       
   311             {
       
   312             // enough space in the end, just append
       
   313             resultPtr.AppendNum( aNum );
       
   314             }
       
   315         }
       
   316 
       
   317     CHAT_DP( D_CHAT_LIT( "CAUtils::GenerateIdLC returning '%S'" ), &resultPtr );
       
   318     return result;
       
   319     }
       
   320 
       
   321 // -----------------------------------------------------------------------------
       
   322 //  CAUtils::ExternalizeBufferToStreamL
       
   323 //  Helper method for externalize the buffer
       
   324 // -----------------------------------------------------------------------------
       
   325 //
       
   326 void CAUtils::ExternalizeBufferToStreamL( const TDesC& aBuffer, RWriteStream& aStream )
       
   327     {
       
   328     aStream.WriteInt32L( aBuffer.Length() );
       
   329     aStream.WriteL( aBuffer );
       
   330     }
       
   331 
       
   332 // -----------------------------------------------------------------------------
       
   333 //  CAUtils::ExternalizeBufferToStreamL
       
   334 //  Helper method for externalize the buffer
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 void CAUtils::ExternalizeBufferToStreamL( const TDesC8& aBuffer, RWriteStream& aStream )
       
   338     {
       
   339     aStream.WriteInt32L( aBuffer.Length() );
       
   340     aStream.WriteL( aBuffer );
       
   341     }
       
   342 
       
   343 // -----------------------------------------------------------------------------
       
   344 // CAUtils::InternalizeBufferFromStreamL
       
   345 // Helper method for internalize the buffer
       
   346 // -----------------------------------------------------------------------------
       
   347 //
       
   348 HBufC* CAUtils::InternalizeBufferFromStreamLC( RReadStream& aStream )
       
   349     {
       
   350     HBufC* buffer = NULL;
       
   351 
       
   352     TInt length = aStream.ReadInt32L();
       
   353 
       
   354     if ( length == 0 )
       
   355         {
       
   356         buffer = KNullDesC().AllocLC();
       
   357         }
       
   358     else
       
   359         {
       
   360         buffer = HBufC::NewLC( length );
       
   361         TPtr ptr( buffer->Des() );
       
   362         aStream.ReadL( ptr, length );
       
   363         }
       
   364 
       
   365     return buffer;
       
   366     }
       
   367 
       
   368 // -----------------------------------------------------------------------------
       
   369 // CAUtils::InternalizeBufferFromStreamL
       
   370 // Helper method for internalize the buffer
       
   371 // -----------------------------------------------------------------------------
       
   372 //
       
   373 HBufC8* CAUtils::InternalizeBuffer8FromStreamLC( RReadStream& aStream )
       
   374     {
       
   375     HBufC8* buffer = NULL;
       
   376 
       
   377     TInt length = aStream.ReadInt32L();
       
   378 
       
   379     if ( length == 0 )
       
   380         {
       
   381         buffer = KNullDesC8().AllocLC();
       
   382         }
       
   383     else
       
   384         {
       
   385         buffer = HBufC8::NewLC( length );
       
   386         TPtr8 ptr( buffer->Des() );
       
   387         aStream.ReadL( ptr, length );
       
   388         }
       
   389 
       
   390     return buffer;
       
   391     }
       
   392 
       
   393 // -----------------------------------------------------------------------------
       
   394 // CAUtils::InternalizeBufferFromStreamL
       
   395 // Helper method for internalize the buffer
       
   396 // -----------------------------------------------------------------------------
       
   397 //
       
   398 HBufC* CAUtils::InternalizeBufferFromStreamL( RReadStream& aStream )
       
   399     {
       
   400     HBufC* buffer = InternalizeBufferFromStreamLC( aStream );
       
   401     CleanupStack::Pop( buffer );
       
   402     return buffer;
       
   403     }
       
   404 
       
   405 // -----------------------------------------------------------------------------
       
   406 // CAUtils::InternalizeBufferFromStreamL
       
   407 // Helper method for internalize the buffer
       
   408 // -----------------------------------------------------------------------------
       
   409 //
       
   410 HBufC8* CAUtils::InternalizeBuffer8FromStreamL( RReadStream& aStream )
       
   411     {
       
   412     HBufC8* buffer = InternalizeBuffer8FromStreamLC( aStream );
       
   413     CleanupStack::Pop( buffer );
       
   414     return buffer;
       
   415     }
       
   416 
       
   417 // -----------------------------------------------------------------------------
       
   418 // CAUtils::ValidLoginIdL()
       
   419 // -----------------------------------------------------------------------------
       
   420 //
       
   421 TBool CAUtils::ValidLoginIdL( const TDesC& aPresenceId )
       
   422     {
       
   423     TBool incorrectDomain ( EFalse );
       
   424     TBool forbiddenChars ( EFalse );
       
   425     TBool incorrectUserPart ( EFalse );
       
   426 
       
   427     HBufC* wvId = aPresenceId.AllocLC();
       
   428     TPtr wvIdPtr = wvId->Des();
       
   429 
       
   430     TInt maxLength ( KServerWVUserIdMaxLength );
       
   431 
       
   432     // let's take out the "wv:" from beginning of user id
       
   433     TInt position( KErrNotFound );
       
   434     if ( KCUImpsId_WVPrefix().CompareF( wvId->Left( KCUImpsId_WVPrefix().Length() ) ) == 0 )
       
   435         {
       
   436         wvIdPtr.Delete( 0, KCUImpsId_WVPrefix().Length() );
       
   437         position = KErrNotFound;
       
   438         // we just took out 3 characters from the id, we have to adjust the max length
       
   439         maxLength = maxLength - KCUImpsId_WVPrefixLength;
       
   440         }
       
   441 
       
   442     // where is "@" ?
       
   443     TInt atIndex( wvId->Find( KCUImpsId_At ) );
       
   444     // we want the domain part without the '@'
       
   445     TPtrC domainPart( wvId->Mid( atIndex + 1 ) );
       
   446 
       
   447     if ( atIndex > 0 )
       
   448         {
       
   449         // check if the domain part is empty
       
   450         if ( domainPart.Length() == 0 )
       
   451             {
       
   452             incorrectDomain = ETrue;
       
   453             }
       
   454         }
       
   455     else if ( atIndex == 0 )
       
   456         {
       
   457         // the '@' is the first character
       
   458         incorrectUserPart = ETrue;
       
   459         }
       
   460 
       
   461     TInt returnValue = domainPart.Find( KCUImpsId_At() );
       
   462     // check the correctness of the domain part
       
   463     if ( returnValue != KErrNotFound )
       
   464         {
       
   465         // extra @-mark found in the domain part
       
   466         incorrectDomain = ETrue;
       
   467         }
       
   468 
       
   469     returnValue = domainPart.Find( KCUImpsId_Dot() );
       
   470     if ( returnValue != KErrNotFound )
       
   471         {
       
   472         // the part after the '.'
       
   473         TPtrC partAfterDot ( domainPart.Mid( returnValue + 1 ) );
       
   474         // the part before the '.'
       
   475         TPtrC partBeforeDot ( domainPart.Left( returnValue ) );
       
   476         // if the '.' is the last character or the first character after the '@'
       
   477         // the domain part is wrong
       
   478         if ( ( 0 == partAfterDot.Length() ) || ( 0 == partBeforeDot.Length() ) )
       
   479             {
       
   480             // the '.' is the last character
       
   481             incorrectDomain = ETrue;
       
   482             }
       
   483         }
       
   484 
       
   485     returnValue = domainPart.Find( KCUImpsId_TwoDots() );
       
   486     if ( returnValue != KErrNotFound )
       
   487         {
       
   488         // there are two sequential dots in the domain part
       
   489         incorrectDomain = ETrue;
       
   490         }
       
   491 
       
   492 
       
   493     // check the wvid for forbidden chars
       
   494 
       
   495     // first we must delete one '@' char if existing
       
   496     position = wvIdPtr.Find( KCUImpsId_At );
       
   497     if ( position != KErrNotFound )
       
   498         {
       
   499         wvIdPtr.Delete( position, KCUImpsId_At().Length() );
       
   500         }
       
   501 
       
   502     returnValue = wvIdPtr.Find( KCUImpsId_WhiteSpace() );
       
   503     // no empty chars allowed in the user part
       
   504     if ( returnValue != KErrNotFound )
       
   505         {
       
   506         forbiddenChars = ETrue;
       
   507         }
       
   508     // no encoded empty chars allowed in the user part
       
   509     returnValue = wvIdPtr.Find( KCUImpsId_WhiteSpaceEnc() );
       
   510     if ( returnValue != KErrNotFound )
       
   511         {
       
   512         forbiddenChars = ETrue;
       
   513         }
       
   514 
       
   515     // no '+' allowed in the user part
       
   516     returnValue = wvIdPtr.Find( KCUImpsId_Plus() );
       
   517     if ( returnValue != KErrNotFound )
       
   518         {
       
   519         forbiddenChars = ETrue;
       
   520         }
       
   521     // no encoded '+' allowed in the user part
       
   522     returnValue = wvIdPtr.Find( KCUImpsId_PlusEnc() );
       
   523     if ( returnValue != KErrNotFound )
       
   524         {
       
   525         forbiddenChars = ETrue;
       
   526         }
       
   527 
       
   528 
       
   529     // no '\t' allowed in the user part
       
   530     returnValue = wvIdPtr.Find( KCUImpsId_Tabulator() );
       
   531     if ( returnValue != KErrNotFound )
       
   532         {
       
   533         forbiddenChars = ETrue;
       
   534         }
       
   535     // no encoded tabulator allowed in the user part
       
   536     returnValue = wvIdPtr.Find( KCUImpsId_TabulatorEnc() );
       
   537     if ( returnValue != KErrNotFound )
       
   538         {
       
   539         forbiddenChars = ETrue;
       
   540         }
       
   541 
       
   542     // no '/' allowed in the user part
       
   543     returnValue = wvIdPtr.Find( KCUImpsId_Slash() );
       
   544     if ( returnValue != KErrNotFound )
       
   545         {
       
   546         forbiddenChars = ETrue;
       
   547         }
       
   548     // no encoded '/' allowed in the user part
       
   549     returnValue = wvIdPtr.Find( KCUImpsId_SlashEnc() );
       
   550     if ( returnValue != KErrNotFound )
       
   551         {
       
   552         forbiddenChars = ETrue;
       
   553         }
       
   554 
       
   555     // no encoded '@' chars allowed in the user part
       
   556     returnValue = wvIdPtr.Find( KCUImpsId_AtEnc() );
       
   557     if ( returnValue != KErrNotFound )
       
   558         {
       
   559         forbiddenChars = ETrue;
       
   560         }
       
   561 
       
   562     TPtr userId = wvId->Des();
       
   563 
       
   564     // no 16bit Unicode chars characters allowed in the user part
       
   565     for ( TInt index = 0; index < wvIdPtr.Length(); index++ )
       
   566         {
       
   567         TUint value = userId[index];
       
   568         // if the character does not fit into 8 bits, it's forbidden 255
       
   569         if ( value > KMAX_LIMIT )
       
   570             {
       
   571             forbiddenChars = ETrue;
       
   572             }
       
   573         }
       
   574 
       
   575     TBool tooLongId ( EFalse );
       
   576 
       
   577     // check if the user id is too long when encoded, but only if there are no forbidden chars
       
   578     if ( !forbiddenChars )
       
   579         {
       
   580         HBufC* encodedUserId = EscapeUtils::EscapeEncodeL( *wvId, EscapeUtils::EEscapeUrlEncoded );
       
   581 
       
   582         if ( atIndex != KErrNotFound )
       
   583             {
       
   584             // @-character was removed from the ID, since it should not be encoded
       
   585             // so the maxlength has to be decreased by it's length
       
   586             maxLength = maxLength - KCUImpsId_At().Length();
       
   587             }
       
   588 
       
   589         if ( encodedUserId->Length() > maxLength )
       
   590             {
       
   591             tooLongId = ETrue;
       
   592             }
       
   593         delete encodedUserId;
       
   594         }
       
   595 
       
   596     CleanupStack::PopAndDestroy( wvId );
       
   597 
       
   598     if ( forbiddenChars )
       
   599         {
       
   600         return EFalse;
       
   601         }
       
   602     else if ( incorrectDomain )
       
   603         {
       
   604         return EFalse;
       
   605         }
       
   606     else if ( tooLongId )
       
   607         {
       
   608         return EFalse;
       
   609         }
       
   610     else if ( incorrectUserPart )
       
   611         {
       
   612         return EFalse;
       
   613         }
       
   614 
       
   615     return ETrue;
       
   616     }
       
   617 
       
   618 
       
   619 // ---------------------------------------------------------
       
   620 // CAUtils::ReconstructIdL
       
   621 // (other items were commented in a header).
       
   622 // ---------------------------------------------------------
       
   623 //
       
   624 HBufC* CAUtils::ReconstructIdL( const TDesC& aOrigId, const TDesC& aUserId )
       
   625     {
       
   626     CHAT_DP( D_CHAT_LIT( "** ReconstructIdL, the original  id: %S" ), &aOrigId );
       
   627     CHAT_DP( D_CHAT_LIT( "** ReconstructIdL, user entered  id: %S" ), &aUserId );
       
   628 
       
   629     // we got user id, add the removed parts ("wv:" and "@something" )
       
   630     TInt colonPos( aOrigId.Locate( KColonUInt ) );
       
   631     TInt domainPos( aOrigId.Locate( KAtUInt ) );
       
   632     TInt userColonPos( aUserId.Locate( KColonUInt ) );
       
   633     TInt userDomainPos( aUserId.Locate( KAtUInt ) );
       
   634 
       
   635     // calculate the new length and determine what additions are needed
       
   636     TInt newLength( aUserId.Length() );
       
   637     TBool addPrefix( EFalse );
       
   638     TBool addDomain( EFalse );
       
   639 
       
   640     if ( colonPos != KErrNotFound &&
       
   641          ( colonPos + 1 ) != aOrigId.Length() &&
       
   642          userColonPos == KErrNotFound )
       
   643         {
       
   644         // the original id had ":" (not last character) and the current one doesn't
       
   645         // => we'll be adding "wv:"
       
   646         newLength += colonPos + 1;
       
   647         addPrefix = ETrue;
       
   648         }
       
   649 
       
   650     if ( domainPos != KErrNotFound && userDomainPos == KErrNotFound )
       
   651         {
       
   652         // the original id had domain and the current one doesn't
       
   653         // => we'll be adding "@something"
       
   654         newLength += aOrigId.Length() - domainPos;
       
   655         addDomain = ETrue;
       
   656         }
       
   657 
       
   658     HBufC* newId = HBufC::NewL( newLength );
       
   659     // NOTE: NO LEAVING METHODS ALLOWED AFTER THIS!
       
   660 
       
   661     TPtr newIdPtr( newId->Des() );
       
   662     newIdPtr.Zero();
       
   663 
       
   664     if ( addPrefix )
       
   665         {
       
   666         // add removed "wv:" prefix
       
   667         newIdPtr.Append( aOrigId.Left( colonPos + 1 ) );
       
   668         }
       
   669     newIdPtr.Append( aUserId );
       
   670     if ( addDomain )
       
   671         {
       
   672         // add removed domain part
       
   673         newIdPtr.Append( aOrigId.Right( aOrigId.Length() - domainPos ) );
       
   674         }
       
   675 
       
   676     CHAT_DP( D_CHAT_LIT( "** ReconstructIdL, reconstructed id: %S" ), &newIdPtr );
       
   677     return newId;
       
   678     }
       
   679 
       
   680 // ---------------------------------------------------------
       
   681 // CAUtils::NeutralFind
       
   682 // ---------------------------------------------------------
       
   683 //
       
   684 TInt CAUtils::NeutralFind( const MDesCArray& aUserList, const TDesC& aUserId )
       
   685     {
       
   686     TInt count( aUserList.MdcaCount() );
       
   687     for ( TInt i( 0 ); i < count; ++i )
       
   688         {
       
   689         if ( CAUtils::NeutralCompare( aUserList.MdcaPoint( i ),
       
   690                                       aUserId ) == 0 )
       
   691             {
       
   692             return i;
       
   693             }
       
   694         }
       
   695     return KErrNotFound;
       
   696     }
       
   697 
       
   698 // ---------------------------------------------------------
       
   699 // Static helper method used in
       
   700 // LanguageSpecificNumberConversion.
       
   701 // ---------------------------------------------------------
       
   702 //
       
   703 static TChar NumberToBase( TChar ch )
       
   704     {
       
   705     TDigitType d[] = { EDigitTypeWestern,
       
   706                        EDigitTypeArabicIndic,
       
   707                        EDigitTypeEasternArabicIndic,
       
   708                        EDigitTypeDevanagari,
       
   709                        EDigitTypeThai
       
   710                      };
       
   711     TInt i = 0;
       
   712     TInt num = sizeof( d ) / sizeof( d[0] );
       
   713     // code scanner warning can be ignored
       
   714     while ( i < num )
       
   715         {
       
   716         if ( ch > TChar( d[i] ) && ch < TChar( d[i] + KMAX_NUMBERBASE ) )
       
   717             {
       
   718             return d[i];
       
   719             }
       
   720         i++;
       
   721         }
       
   722 
       
   723     return ch;
       
   724     }
       
   725 
       
   726 // ---------------------------------------------------------
       
   727 // CAUtils::LanguageSpecificNumberConversion
       
   728 // ---------------------------------------------------------
       
   729 //
       
   730 void CAUtils::LanguageSpecificNumberConversion( TDes& aDes )
       
   731     {
       
   732     // Get current locale and digit type
       
   733     TLocale locale;
       
   734     locale.Refresh();
       
   735     TDigitType digitType = locale.DigitType();
       
   736 
       
   737     // Check if conversion is needed
       
   738     TBool conversion = ( digitType == EDigitTypeArabicIndic )
       
   739                        || ( digitType == EDigitTypeEasternArabicIndic )
       
   740                        || ( digitType == EDigitTypeDevanagari );
       
   741 
       
   742     if ( !conversion )
       
   743         {
       
   744         // Don't do anything
       
   745         return;
       
   746         }
       
   747 
       
   748     // Do conversion, logic for this conversion
       
   749     // comes from AknTextUtils::LanguageSpecificNumberConversion.
       
   750     // Logic is copied here to avoid using Avkon in engine side.
       
   751     TChar toArea = KCharToArea;
       
   752 
       
   753     switch ( digitType )
       
   754         {
       
   755         case EDigitTypeWestern:
       
   756         case EDigitTypeArabicIndic:
       
   757         case EDigitTypeEasternArabicIndic:
       
   758         case EDigitTypeDevanagari:
       
   759         case EDigitTypeThai:    // Flowthrough
       
   760             {
       
   761             toArea = digitType;
       
   762             break;
       
   763             }
       
   764         case EDigitTypeUnknown:
       
   765         case EDigitTypeAllTypes:
       
   766         default:    // Flowthrough
       
   767             {
       
   768             return;
       
   769             }
       
   770         }
       
   771 
       
   772     TInt length = aDes.Length();
       
   773 
       
   774     for ( TInt i = 0; i < length; i++ )
       
   775         {
       
   776         TChar ch = aDes[i];
       
   777         TChar fromArea = NumberToBase( ch );
       
   778         TChar::TBdCategory cat = ch.GetBdCategory();
       
   779         switch ( cat )
       
   780             {
       
   781             case TChar::EArabicNumber:
       
   782             case TChar::EEuropeanNumber:    // Flowthrough
       
   783                 {
       
   784                 ch += toArea;
       
   785                 ch -= fromArea;
       
   786                 aDes[i] = TUint16( ch );
       
   787                 break;
       
   788                 }
       
   789             default:
       
   790                 {
       
   791                 break;
       
   792                 }
       
   793             }
       
   794         }
       
   795     }
       
   796 // ---------------------------------------------------------
       
   797 // CAUtils::CapitalizeListNameL : UI CR :  101-39727
       
   798 // ---------------------------------------------------------
       
   799 //
       
   800 HBufC* CAUtils::CapitalizeListNameL( const TDesC& aListname )
       
   801     {
       
   802     MCAStoredContacts* contacts = NULL;
       
   803     TRAPD( err, contacts = CCAStorageManagerFactory::ContactListInterfaceL() );
       
   804 
       
   805     if ( err == KErrNone && contacts
       
   806          && contacts->CapitalizingEnabled()
       
   807          && ( aListname.Length() ) )
       
   808         {
       
   809         HBufC* capitalPartBuf = HBufC::NewL( KServerWVUserIdMaxLength );
       
   810         TPtr capitalPartptr( capitalPartBuf->Des() );
       
   811 
       
   812         if ( aListname.Length() == 1 )
       
   813             {
       
   814             capitalPartptr.CopyUC( aListname );
       
   815             return capitalPartBuf;
       
   816             }
       
   817         capitalPartptr.CopyUC( aListname.Left( 1 ) );// copy and capitalize first letter
       
   818         capitalPartptr.Append( aListname.Right( ( aListname.Length() - 1 ) ) );// append the remaining
       
   819         return capitalPartBuf;
       
   820         }
       
   821 
       
   822     // some error, don't modify
       
   823     CHAT_DP_FUNC_DP( "CapitalizeListNameL", "Got some error, not Capitalizing" );
       
   824     HBufC* capitalPartBuf = aListname.AllocL();
       
   825     return capitalPartBuf;
       
   826     }
       
   827 
       
   828 
       
   829 // ---------------------------------------------------------
       
   830 // CAUtils::CapitalizingEnabled   UI CR : 101-39727
       
   831 // ---------------------------------------------------------
       
   832 //
       
   833 TBool CAUtils::CapitalizingEnabled()
       
   834     {
       
   835     MCAStoredContacts* contacts = NULL;
       
   836     TRAPD( err, contacts = CCAStorageManagerFactory::ContactListInterfaceL() );
       
   837     if ( err != KErrNone || !contacts )
       
   838         {
       
   839         // some error, return Efalse
       
   840         return EFalse;
       
   841         }
       
   842     return ( contacts->CapitalizingEnabled() );
       
   843     }
       
   844 
       
   845 
       
   846 // ---------------------------------------------------------
       
   847 // CAUtils::CapitalizeListNameL   UI CR : 101-39727
       
   848 // ---------------------------------------------------------
       
   849 //
       
   850 
       
   851 HBufC* CAUtils::CapitalizeListIdL( const TDesC& aId )
       
   852     {
       
   853     TPtrC ret( aId );
       
   854     TBool slashfound( EFalse );
       
   855     TBool domainfound( EFalse );
       
   856     // locate "/" for list id.
       
   857     TInt pos = aId.FindC( KSlash  );
       
   858 
       
   859     if ( ( pos != KErrNotFound ) && ( pos != aId.Length() - 1 ) )
       
   860         {
       
   861         // make it true if slash found and it should not be at the last position
       
   862         slashfound = ETrue;
       
   863         }
       
   864 
       
   865     // locate for the domain part
       
   866 
       
   867     TInt domainPos = ret.FindC( KAt );
       
   868     if ( ( domainPos != KErrNotFound ) && ( domainPos != 0 ) )
       
   869         {
       
   870         // make it true if domain part is found and itshould not be at the first position
       
   871         domainfound = ETrue;
       
   872         }
       
   873 
       
   874     MCAStoredContacts* contacts = NULL;
       
   875     TRAPD( err, contacts = CCAStorageManagerFactory::ContactListInterfaceL() );
       
   876 
       
   877     if ( err == KErrNone && contacts                      // extrachecking here bcoz
       
   878          && contacts->CapitalizingEnabled()// it has to return NULL
       
   879          && aId.Length() )                 // (not the list id)
       
   880         {                                                   // if error occurs
       
   881         if ( slashfound && !domainfound )
       
   882             {
       
   883             //remove upto  '/' and capitalize
       
   884             return  CAUtils::CapitalizeListNameL( aId.Right( ( aId.Length() - ( pos + 1 ) ) ) );
       
   885             }
       
   886         else  if ( slashfound && domainfound )
       
   887             {
       
   888             // remove upto  '/' and after domain part and capitalize
       
   889             return CAUtils::CapitalizeListNameL( aId.Mid( pos + 1, ( domainPos - pos - 1 ) ) );
       
   890             }
       
   891         else
       
   892             {
       
   893             // if only domain part found or both part not found just capitalize listId
       
   894             return CAUtils::CapitalizeListNameL( aId );
       
   895             }
       
   896 
       
   897         }
       
   898 
       
   899     // some error,return null
       
   900     return NULL;
       
   901     }
       
   902 
       
   903 // End of file