diff -r 000000000000 -r ff3b6d0fd310 cbs/CbsServer/ServerSrc/Ccbsrecdecoder.cpp --- /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 +#include +#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 generatedUnicode; + TInt state( CCnvCharacterSetConverter::KStateDefault ); // has to be ref. + + // Remove all trailing control characters from the end of the Cell info msg + TBuf8 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