--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cbs/CbsServer/ServerSrc/Ccbsrecdecoder.cpp Tue Feb 02 01:11:09 2010 +0200
@@ -0,0 +1,368 @@
+/*
+* Copyright (c) 2003 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: This module contains the implementation of CCbsRecDecoder class
+* member functions.
+*
+* CCCbsRecDecoder handles decoding of message contents.
+*
+* CbsServer receives messages stored in 8-bit descriptors
+* from ETel. This class converts them into 16-bit descriptors
+* and decodes the message representation into UCS-2 (which
+* is used by Symbian OS internally).
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <e32svr.h>
+#include <charconv.h>
+#include "CbsServerConstants.h"
+#include "CCbsRecDecoder.h"
+#include "CCbsMessage.h"
+#include "CCbsRecMessage.h"
+#include "CCbsRecWcdmaMessage.h"
+#include "CbsLogger.h"
+
+// CONSTANTS
+
+// Max characters in generated unicode
+const TInt KMaxCharsInGeneratedUnicode = 128;
+
+// ================= MEMBER FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// CCbsMcnSession::CCbsMcnSession
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CCbsRecDecoder::CCbsRecDecoder()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCbsRecDecoder::ConstructL()
+ {
+ iConverter = CCnvCharacterSetConverter::NewL();
+ User::LeaveIfError( iFs.Connect() );
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CCbsRecDecoder* CCbsRecDecoder::NewL()
+ {
+ CCbsRecDecoder* self = new(ELeave) CCbsRecDecoder;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+// Destructor
+CCbsRecDecoder::~CCbsRecDecoder()
+ {
+ CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::~CCbsRecDecoder()");
+ iFs.Close();
+ delete iConverter;
+ CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::~CCbsRecDecoder()");
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::DecodeL
+// Decodes 7-bit, 8-bit and 16-bit representations into UCS-2.
+// If the message has a language indication prefixed
+// in the message body, the indication is removed.
+// Compressed messages are not supported.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCbsRecDecoder::DecodeL(
+ CCbsMessage& aMessage )
+ {
+ if ( aMessage.IsCompressed() )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ // Convert message into plaintext.
+ DoDecodeL( aMessage );
+
+ // 8-bit representation not needed anymore.
+ aMessage.ReleaseEightBitRepresentation();
+
+ // Determine language of this message (from header or content),
+ aMessage.ResolveLanguage();
+
+ // Remove language indication, if present, from message.
+ aMessage.RemoveLanguageIndicationFromBodyL();
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::DoDecodeL
+// Decodes the given message's content.
+// Decodes aMessage's 7-bit/Unicode representation
+// into internal Unicode representation.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCbsRecDecoder::DoDecodeL(
+ CCbsMessage& aMessage )
+ {
+ CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::DoDecodeL()");
+
+ TCbsRecAlphabet alphabet( aMessage.Alphabet() );
+ if ( alphabet == ECbsRecAlphabetDefault ||
+ alphabet == ECbsRecAlphabetUnspecified )
+ {
+ DefaultAlphabetDecodeL( aMessage );
+ }
+ else if ( alphabet == ECbsRecAlphabet8bit )
+ {
+ EightbitAlphabetDecodeL( aMessage );
+ }
+ else
+ {
+ UnicodeDecodeL( aMessage );
+ }
+ CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::DoDecodeL()");
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::UnicodeDecodeL
+// Decodes 8-bit and Unicode message representations.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCbsRecDecoder::UnicodeDecodeL(
+ CCbsMessage& aMsg )
+ {
+ CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::UnicodeDecodeL()");
+
+ TPtrC8 contents( aMsg.Contents8() );
+
+ // Reserve enough space for the actual contents plus
+ // the CR key
+ aMsg.ReserveContentSizeL( contents.Length()+1 );
+
+ // Check if the message is preceded with language.
+ if( aMsg.DCS() == DCS_MPLI_UCS2 )
+ {
+ // The language is encoded as 7-bit USSD. Unpack that
+ // and add CR after the language to match the default
+ // alphabet case.
+ TBuf<3> language;
+ language.Copy( contents.Left(2) );
+ language[1] <<= 1;
+ language[1] |= (language[0] & 0x80) >> 7;
+ language[0] &= 0x7f;
+ language.Append( EKeyEnter );
+ aMsg.AppendContent( language );
+
+ // Skip the language indication
+ contents.Set( contents.Mid(2) );
+ }
+
+ // The rest of the message is UCS2 encoded Unicode.
+ // Make sure the byte order is correct.
+ HBufC* text = HBufC::NewL( contents.Length() / 2 );
+ CleanupStack::PushL( text );
+
+ TPtr ptr( text->Des() );
+ TInt length( contents.Length() );
+
+ // If the length is an odd number, remove the last character.
+ if ( length & 0x01 )
+ {
+ length -= 1;
+ }
+
+ for ( TInt i( 0 ); i < length; i += 2 )
+ {
+ ptr.Append( ( contents[ i ] << 8 ) + contents[ i + 1 ] );
+ }
+
+ aMsg.AppendContent( RemoveTrailingCR( *text ) );
+ CleanupStack::PopAndDestroy();
+
+ CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::UnicodeDecodeL()");
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::DefaultAlphabetDecodeL
+// Decodes 7-bit message representation.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCbsRecDecoder::DefaultAlphabetDecodeL(
+ CCbsMessage& aMsg )
+ {
+ CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::DefaultAlphabetDecodeL()");
+
+ // Check that the converter is available
+ CCnvCharacterSetConverter* characterSetConverter =
+ CCnvCharacterSetConverter::NewLC(); // on CS
+
+ CCnvCharacterSetConverter::TAvailability availability =
+ characterSetConverter->PrepareToConvertToOrFromL(
+ KCharacterSetIdentifierSms7Bit, iFs );
+
+ if ( availability == CCnvCharacterSetConverter::ENotAvailable )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ // Allocate a buffer for the cleartext message
+ TBuf8< KCbsMaxCharsInPage + 1 > realMsg;
+
+ // Get a pointer to the encoded message
+ TPtrC8 msgPartOfEtelMsg = aMsg.Contents8();
+
+ // Length of the cleartext message.
+ TInt messageLength( ( msgPartOfEtelMsg.Length() * 8 ) / 7 );
+
+ static const TUint mask_table[ 8 ] =
+ { 0x7F, 0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F };
+ TUint8 si,di; // Indexes
+ TInt tmp_modulo; // Temporary; to improve efficiency
+ si = 0;
+
+ // The location of the current 7-bit character determines the
+ // action to be taken. Only every 7th character is not divided into
+ // two bytes. All other characters will have to be contructed by
+ // combining bits of two consequent bytes.
+
+ for ( di = 0; di < messageLength; di++ )
+ {
+ TUint num2 = 0;
+ tmp_modulo = di % 8;
+ switch ( tmp_modulo )
+ {
+ case 0:
+ num2 = msgPartOfEtelMsg[ si ] & 0x7F;
+ realMsg.Append( num2 );
+ break;
+ case 7:
+ num2 = ( msgPartOfEtelMsg[ si ] >> 1 ) & 0x7F;
+ realMsg.Append( num2 );
+ si++;
+ break;
+ default:
+ num2 = msgPartOfEtelMsg[ si ] >> ( 8 - ( tmp_modulo ) );
+ num2 &= mask_table[ tmp_modulo ];
+ num2 |= msgPartOfEtelMsg[ si + 1 ] << ( tmp_modulo );
+ num2 &= 0x7F;
+ realMsg.Append( num2 );
+ si++;
+ break;
+ }//switch( tmp_modulo )
+ }//for
+
+ TBuf16<KMaxCharsInGeneratedUnicode> generatedUnicode;
+ TInt state( CCnvCharacterSetConverter::KStateDefault ); // has to be ref.
+
+ // Remove all trailing control characters from the end of the Cell info msg
+ TBuf8<KCbsMaxCharsInPage> cleanedMsg;
+ if ( aMsg.TopicNumber() == KCellInfoTopic )
+ {
+ cleanedMsg = RemoveTrailingControlChars( realMsg );
+ User::LeaveIfError( characterSetConverter->ConvertToUnicode(
+ generatedUnicode, cleanedMsg, state ) );
+ }
+ else
+ {
+ User::LeaveIfError( characterSetConverter->ConvertToUnicode(
+ generatedUnicode, realMsg, state ) );
+ }
+
+ CleanupStack::PopAndDestroy(); // characterSetConverter
+
+ aMsg.ReserveContentSizeL( messageLength );
+ aMsg.AppendContent( RemoveTrailingCR( generatedUnicode ) );
+
+ CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::DefaultAlphabetDecodeL()");
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::EightbitAlphabetDecodeL
+// Decodes 8-bit message representation.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCbsRecDecoder::EightbitAlphabetDecodeL(
+ CCbsMessage& aMsg )
+ {
+ CBSLOGSTRING("CBSSERVER: >>> CCbsRecDecoder::EightbitAlphabetDecodeL()");
+
+ // Copy 8-bit representation to 16-bit
+ HBufC* hbuf = HBufC::NewL( aMsg.Contents8().Length() );
+ CleanupStack::PushL( hbuf );
+
+ TPtr16 ptr16 = hbuf->Des();
+ ptr16.Copy( aMsg.Contents8() );
+
+ // Reserve enough space for the actual contents
+ aMsg.ReserveContentSizeL( aMsg.Contents8().Length() );
+ aMsg.AppendContent( RemoveTrailingCR( *hbuf ) );
+
+ CleanupStack::PopAndDestroy( hbuf );
+
+ CBSLOGSTRING("CBSSERVER: <<< CCbsRecDecoder::EightbitAlphabetDecodeL()");
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::RemoveTrailingCR
+// Removes the trailing CRs from a message.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPtrC CCbsRecDecoder::RemoveTrailingCR(
+ const TDesC& aText )
+ {
+ TInt i( aText.Length() );
+ for ( ; i > 0 && aText[ i - 1 ] == EKeyEnter; i-- )
+ {
+ // nothing
+ }
+
+ return aText.Left( i );
+ }
+
+// -----------------------------------------------------------------------------
+// CCbsRecDecoder::RemoveTrailingControlChars
+// Removes the trailing control characters from a message.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TPtrC8 CCbsRecDecoder::RemoveTrailingControlChars(
+ const TDesC8& aText )
+ {
+ TInt i( aText.Length() );
+ for ( ; i > 0 && ( aText[ i - 1 ] == EKeyEnter || aText[ i - 1 ] == EKeyLineFeed ); i-- )
+ {
+ // nothing
+ }
+
+ return aText.Left( i );
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+// End of File