cbs/CbsServer/ServerSrc/Ccbsrecdecoder.cpp
changeset 46 2fa1fa551b0b
parent 42 35488577e233
child 48 78df25012fda
equal deleted inserted replaced
42:35488577e233 46:2fa1fa551b0b
     1 /*
       
     2 * Copyright (c) 2003 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:  This module contains the implementation of CCbsRecDecoder class 
       
    15 *                member functions.
       
    16 *    
       
    17 *                CCCbsRecDecoder handles decoding of message contents.
       
    18 *
       
    19 *                CbsServer receives messages stored in 8-bit descriptors
       
    20 *                from ETel. This class converts them into 16-bit descriptors
       
    21 *                and decodes the message representation into UCS-2 (which
       
    22 *                is used by Symbian OS internally). 
       
    23 *
       
    24 */
       
    25 
       
    26 
       
    27 // INCLUDE FILES
       
    28 
       
    29 #include <e32svr.h>
       
    30 #include <charconv.h>
       
    31 #include "CbsServerConstants.h"
       
    32 #include "CCbsRecDecoder.h"
       
    33 #include "CCbsMessage.h"
       
    34 #include "CCbsRecMessage.h"
       
    35 #include "CCbsRecWcdmaMessage.h"
       
    36 #include "CbsLogger.h"
       
    37 
       
    38 // CONSTANTS
       
    39 
       
    40 // Max characters in generated unicode 
       
    41 const TInt KMaxCharsInGeneratedUnicode = 128;   
       
    42 
       
    43 // ================= MEMBER FUNCTIONS =======================
       
    44 
       
    45 // -----------------------------------------------------------------------------
       
    46 // CCbsMcnSession::CCbsMcnSession
       
    47 // C++ default constructor can NOT contain any code, that
       
    48 // might leave.
       
    49 // -----------------------------------------------------------------------------
       
    50 //
       
    51 CCbsRecDecoder::CCbsRecDecoder()
       
    52     {
       
    53     }
       
    54 
       
    55 // -----------------------------------------------------------------------------
       
    56 // CCbsRecDecoder::ConstructL
       
    57 // Symbian 2nd phase constructor can leave.
       
    58 // -----------------------------------------------------------------------------
       
    59 //
       
    60 void CCbsRecDecoder::ConstructL()
       
    61     {
       
    62     iConverter = CCnvCharacterSetConverter::NewL();
       
    63     User::LeaveIfError( iFs.Connect() );
       
    64     }     
       
    65 
       
    66 // -----------------------------------------------------------------------------
       
    67 // CCbsRecDecoder::NewL
       
    68 // Two-phased constructor.
       
    69 // -----------------------------------------------------------------------------
       
    70 //
       
    71 CCbsRecDecoder* CCbsRecDecoder::NewL()
       
    72     {
       
    73     CCbsRecDecoder* self = new(ELeave) CCbsRecDecoder;
       
    74     CleanupStack::PushL( self );
       
    75     self->ConstructL();
       
    76     CleanupStack::Pop();
       
    77     return self;
       
    78     }
       
    79     
       
    80 // Destructor
       
    81 CCbsRecDecoder::~CCbsRecDecoder()
       
    82     {
       
    83     CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::~CCbsRecDecoder()");    
       
    84     iFs.Close();
       
    85     delete iConverter;
       
    86     CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::~CCbsRecDecoder()");
       
    87     }
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CCbsRecDecoder::DecodeL
       
    91 // Decodes 7-bit, 8-bit and 16-bit representations into UCS-2.
       
    92 // If the message has a language indication prefixed
       
    93 // in the message body, the indication is removed.
       
    94 // Compressed messages are not supported.
       
    95 // (other items were commented in a header).
       
    96 // -----------------------------------------------------------------------------
       
    97 //
       
    98 void CCbsRecDecoder::DecodeL( 
       
    99     CCbsMessage& aMessage )
       
   100     {
       
   101     if ( aMessage.IsCompressed() )
       
   102         {
       
   103         User::Leave( KErrNotSupported );
       
   104         }
       
   105 
       
   106     // Convert message into plaintext.
       
   107     DoDecodeL( aMessage );
       
   108 
       
   109     // 8-bit representation not needed anymore.
       
   110     aMessage.ReleaseEightBitRepresentation();
       
   111 
       
   112     // Determine language of this message (from header or content),
       
   113     aMessage.ResolveLanguage();
       
   114 
       
   115     // Remove language indication, if present, from message.
       
   116     aMessage.RemoveLanguageIndicationFromBodyL();
       
   117     }
       
   118 
       
   119 // -----------------------------------------------------------------------------
       
   120 // CCbsRecDecoder::DoDecodeL
       
   121 // Decodes the given message's content. 
       
   122 // Decodes aMessage's 7-bit/Unicode representation
       
   123 // into internal Unicode representation.
       
   124 // (other items were commented in a header).
       
   125 // -----------------------------------------------------------------------------
       
   126 //
       
   127 void CCbsRecDecoder::DoDecodeL( 
       
   128     CCbsMessage& aMessage )
       
   129     {
       
   130     CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::DoDecodeL()");
       
   131     
       
   132     TCbsRecAlphabet alphabet( aMessage.Alphabet() );
       
   133     if ( alphabet == ECbsRecAlphabetDefault || 
       
   134          alphabet == ECbsRecAlphabetUnspecified )
       
   135         {
       
   136         DefaultAlphabetDecodeL( aMessage );
       
   137         }
       
   138     else if ( alphabet == ECbsRecAlphabet8bit )
       
   139         {
       
   140         EightbitAlphabetDecodeL( aMessage );
       
   141         }
       
   142     else
       
   143         {
       
   144         UnicodeDecodeL( aMessage );
       
   145         }
       
   146     CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::DoDecodeL()");
       
   147     }
       
   148     
       
   149 // -----------------------------------------------------------------------------
       
   150 // CCbsRecDecoder::UnicodeDecodeL
       
   151 // Decodes 8-bit and Unicode message representations.
       
   152 // (other items were commented in a header).
       
   153 // -----------------------------------------------------------------------------
       
   154 //
       
   155 void CCbsRecDecoder::UnicodeDecodeL( 
       
   156     CCbsMessage& aMsg )
       
   157     {
       
   158     CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::UnicodeDecodeL()");
       
   159     
       
   160     TPtrC8 contents( aMsg.Contents8() );
       
   161 
       
   162     // Reserve enough space for the actual contents plus
       
   163     // the CR key
       
   164     aMsg.ReserveContentSizeL( contents.Length()+1 );
       
   165 
       
   166     // Check if the message is preceded with language.
       
   167     if( aMsg.DCS() == DCS_MPLI_UCS2 )
       
   168         {
       
   169         // The language is encoded as 7-bit USSD. Unpack that
       
   170         // and add CR after the language to match the default
       
   171         // alphabet case.
       
   172         TBuf<3> language;
       
   173         language.Copy( contents.Left(2) );
       
   174         language[1] <<= 1;
       
   175         language[1] |= (language[0] & 0x80) >> 7;
       
   176         language[0] &= 0x7f;
       
   177         language.Append( EKeyEnter );
       
   178         aMsg.AppendContent( language );
       
   179 
       
   180         // Skip the language indication
       
   181         contents.Set( contents.Mid(2) );
       
   182         }
       
   183 
       
   184     // The rest of the message is UCS2 encoded Unicode. 
       
   185     // Make sure the byte order is correct.
       
   186     HBufC* text = HBufC::NewL( contents.Length() / 2 );
       
   187     CleanupStack::PushL( text );
       
   188 
       
   189     TPtr ptr( text->Des() );
       
   190     TInt length( contents.Length() );
       
   191 
       
   192     // If the length is an odd number, remove the last character.
       
   193     if ( length & 0x01 )
       
   194         {
       
   195         length -= 1;
       
   196         }
       
   197 
       
   198     for ( TInt i( 0 ); i < length; i += 2 )
       
   199         {
       
   200         ptr.Append( ( contents[ i ] << 8 ) + contents[ i + 1 ] );
       
   201         }
       
   202 
       
   203     aMsg.AppendContent( RemoveTrailingCR( *text ) );
       
   204     CleanupStack::PopAndDestroy();
       
   205     
       
   206     CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::UnicodeDecodeL()");
       
   207     }
       
   208    
       
   209 // -----------------------------------------------------------------------------
       
   210 // CCbsRecDecoder::DefaultAlphabetDecodeL
       
   211 // Decodes 7-bit message representation.
       
   212 // (other items were commented in a header).
       
   213 // -----------------------------------------------------------------------------
       
   214 //
       
   215 void CCbsRecDecoder::DefaultAlphabetDecodeL( 
       
   216     CCbsMessage& aMsg )
       
   217     {
       
   218     CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::DefaultAlphabetDecodeL()");
       
   219     
       
   220     // Check that the converter is available
       
   221     CCnvCharacterSetConverter* characterSetConverter = 
       
   222         CCnvCharacterSetConverter::NewLC(); // on CS
       
   223 
       
   224     CCnvCharacterSetConverter::TAvailability availability = 
       
   225         characterSetConverter->PrepareToConvertToOrFromL(
       
   226             KCharacterSetIdentifierSms7Bit, iFs );
       
   227 
       
   228     if ( availability == CCnvCharacterSetConverter::ENotAvailable )
       
   229         {
       
   230         User::Leave( KErrNotFound );
       
   231         }
       
   232 
       
   233     // Allocate a buffer for the cleartext message
       
   234     TBuf8< KCbsMaxCharsInPage + 1 > realMsg;
       
   235 
       
   236     // Get a pointer to the encoded message
       
   237     TPtrC8 msgPartOfEtelMsg = aMsg.Contents8();
       
   238 
       
   239     // Length of the cleartext message.
       
   240     TInt messageLength( ( msgPartOfEtelMsg.Length() * 8 ) / 7 );
       
   241 
       
   242     static const TUint mask_table[ 8 ] = 
       
   243 			    { 0x7F, 0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F };
       
   244     TUint8  si,di;            // Indexes
       
   245     TInt  tmp_modulo;         // Temporary; to improve efficiency
       
   246     si = 0;
       
   247 
       
   248     // The location of the current 7-bit character determines the
       
   249     // action to be taken. Only every 7th character is not divided into
       
   250     // two bytes. All other characters will have to be contructed by
       
   251     // combining bits of two consequent bytes.
       
   252 
       
   253     for ( di = 0; di < messageLength; di++ )
       
   254 	    {
       
   255 	    TUint num2 = 0;
       
   256 	    tmp_modulo = di % 8;
       
   257 	    switch ( tmp_modulo )
       
   258 	        {
       
   259 	        case 0:
       
   260 		        num2 = msgPartOfEtelMsg[ si ] & 0x7F;
       
   261 		        realMsg.Append( num2 );
       
   262 		        break;
       
   263 	        case 7:
       
   264 		        num2 = ( msgPartOfEtelMsg[ si ] >> 1 ) & 0x7F;
       
   265 		        realMsg.Append( num2 );
       
   266 		        si++;
       
   267 		        break;
       
   268 	        default:
       
   269 	            num2 = msgPartOfEtelMsg[ si ] >> ( 8 - ( tmp_modulo ) );
       
   270 	            num2 &= mask_table[ tmp_modulo ];
       
   271 	            num2 |= msgPartOfEtelMsg[ si + 1 ] << ( tmp_modulo );
       
   272 	            num2 &= 0x7F;
       
   273 	            realMsg.Append( num2 );
       
   274 	            si++;
       
   275 	        break;
       
   276 	        }//switch( tmp_modulo )
       
   277 	    }//for
       
   278 
       
   279     TBuf16<KMaxCharsInGeneratedUnicode> generatedUnicode;
       
   280     TInt state( CCnvCharacterSetConverter::KStateDefault ); // has to be ref.
       
   281     
       
   282     // Remove all trailing control characters from the end of the Cell info msg
       
   283     TBuf8<KCbsMaxCharsInPage> cleanedMsg;
       
   284     if ( aMsg.TopicNumber() == KCellInfoTopic )
       
   285         {
       
   286         cleanedMsg = RemoveTrailingControlChars( realMsg );
       
   287         User::LeaveIfError( characterSetConverter->ConvertToUnicode(
       
   288             generatedUnicode, cleanedMsg, state ) );
       
   289         }
       
   290     else
       
   291         {
       
   292         User::LeaveIfError( characterSetConverter->ConvertToUnicode(
       
   293             generatedUnicode, realMsg, state ) );
       
   294         } 
       
   295     
       
   296     CleanupStack::PopAndDestroy(); // characterSetConverter
       
   297     
       
   298     aMsg.ReserveContentSizeL( messageLength );
       
   299     aMsg.AppendContent( RemoveTrailingCR( generatedUnicode ) );
       
   300     
       
   301     CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::DefaultAlphabetDecodeL()");
       
   302     }
       
   303     
       
   304 // -----------------------------------------------------------------------------
       
   305 // CCbsRecDecoder::EightbitAlphabetDecodeL
       
   306 // Decodes 8-bit message representation.
       
   307 // (other items were commented in a header).
       
   308 // -----------------------------------------------------------------------------
       
   309 //
       
   310 void CCbsRecDecoder::EightbitAlphabetDecodeL( 
       
   311     CCbsMessage& aMsg )
       
   312     {
       
   313     CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::EightbitAlphabetDecodeL()");
       
   314     
       
   315     // Copy 8-bit representation to 16-bit
       
   316     HBufC* hbuf = HBufC::NewL( aMsg.Contents8().Length() );
       
   317     CleanupStack::PushL( hbuf );
       
   318     
       
   319     TPtr16 ptr16 = hbuf->Des();     
       
   320     ptr16.Copy( aMsg.Contents8() );        
       
   321     
       
   322     // Reserve enough space for the actual contents    
       
   323     aMsg.ReserveContentSizeL( aMsg.Contents8().Length() );  
       
   324     aMsg.AppendContent( RemoveTrailingCR( *hbuf ) );
       
   325     
       
   326     CleanupStack::PopAndDestroy( hbuf );
       
   327     
       
   328     CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::EightbitAlphabetDecodeL()");
       
   329     }
       
   330 
       
   331 // -----------------------------------------------------------------------------
       
   332 // CCbsRecDecoder::RemoveTrailingCR
       
   333 // Removes the trailing CRs from a message.
       
   334 // (other items were commented in a header).
       
   335 // -----------------------------------------------------------------------------
       
   336 //
       
   337 TPtrC CCbsRecDecoder::RemoveTrailingCR( 
       
   338     const TDesC& aText )
       
   339     {
       
   340     TInt i( aText.Length() );
       
   341     for ( ; i > 0 && aText[ i - 1 ] == EKeyEnter; i-- )
       
   342         {
       
   343         // nothing
       
   344         }
       
   345 
       
   346     return aText.Left( i );
       
   347     }
       
   348     
       
   349 // -----------------------------------------------------------------------------
       
   350 // CCbsRecDecoder::RemoveTrailingControlChars
       
   351 // Removes the trailing control characters from a message.
       
   352 // (other items were commented in a header).
       
   353 // -----------------------------------------------------------------------------
       
   354 //
       
   355 TPtrC8 CCbsRecDecoder::RemoveTrailingControlChars( 
       
   356     const TDesC8& aText )
       
   357     {
       
   358     TInt i( aText.Length() );
       
   359     for ( ; i > 0 && ( aText[ i - 1 ] == EKeyEnter || aText[ i - 1 ] == EKeyLineFeed ); i-- )
       
   360         {
       
   361         // nothing
       
   362         }
       
   363 
       
   364     return aText.Left( i );
       
   365     }
       
   366 
       
   367 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   368 //  End of File