diff -r 000000000000 -r 3553901f7fa8 smsprotocols/smsstack/ems/src/EMSInformationElement.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/smsprotocols/smsstack/ems/src/EMSInformationElement.cpp Tue Feb 02 01:41:59 2010 +0200 @@ -0,0 +1,342 @@ +/* +* Copyright (c) 2009 Sony Ericsson Mobile Communications AB +* 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: +* Sony Ericsson Mobile Communications AB - initial contribution. +* Nokia Corporation - additional changes. +* +* Contributors: +* +* Description: +* Implements the Enhanced SMS Animation Information Element. +* +*/ + + +/** + * @file + * + * Implements EMSInformationElement class + */ + +#include +#include +#include +#include +#include +#include +#include + + +EXPORT_C void CEmsInformationElement::SetStartPosition(TUint aValue) +/** + * @capability None + */ + { + iStartPosition = aValue; + } + +EXPORT_C TUint CEmsInformationElement::StartPosition() const +/** + * @capability None + */ + { + return iStartPosition; + } + +EXPORT_C TInt CEmsInformationElement::Length() const +/** + * @capability None + */ + { + // The length includes the IE header (IEID, IEL) and the + // start position, if applicable, plus the encoded body length + TInt len = 2 + iEncodedBodyLength; + if (iStartPosEncoded) + { + ++len; + } + + return len; + } + + +/** + * Encodes the EmsInformationElement into a CSmsInformationElement + * + * @param aSmsIe SMS information element to encode into + */ +EXPORT_C void CEmsInformationElement::EncodeInformationElementL() +/** + * @capability None + */ + { + TInt ieLength = iEncodedBodyLength; + + // if start position is to be encoded, then increment this length + if (iStartPosEncoded) + { + ++ieLength; + } + + // Create a new body for the IE + NewDataL(ieLength); + + // Get the raw data to be encoded + TPtr8 ptr(Data()); + ptr.SetLength(0); + + // Encode start position if required + if (iStartPosEncoded) + { + ptr.Append(static_cast(iStartPosition)); + } + + // Call the specific encode body function - false indicates NOT + // for serialisation + EncodeBodyL(ptr, EFalse); + } + +CEmsInformationElement* CEmsInformationElement::DecodeInformationElementL(const CSmsInformationElement& aSmsIe) + { + // Firstly, create the element given the ID + CEmsInformationElement* elem = CEmsFactory::CreateIeL(aSmsIe.Identifier()); + + if (!elem) + { + User::Leave(KErrCorrupt); + } + + CleanupStack::PushL(elem); + + // now decode the rest of the element + const TUint8* ptr; + const TDesC8& des = aSmsIe.Data(); + TInt length = des.Length(); + + if (length <= 0) + User::Leave(KErrCorrupt); + + // If the start position is encoded, then decode it, and add back + // in the start position offset + if (elem->iStartPosEncoded) + { + elem->iStartPosition = des[0]; + + // set the pointer to point to the first element, and + // reduce the length by 1; + ptr = &des[1]; + --length; + } + + else + { + // otherwise, set it to the first element + ptr = &des[0]; + } + + // set the encoded body length to be what's left over + elem->iEncodedBodyLength = length; + + // Now call the specific decode body function. + elem->DecodeBodyL(TPtrC8(ptr, length), EFalse); + + CleanupStack::Pop(elem); + return elem; + } + +void CEmsInformationElement::ExternalizeL(RWriteStream& aStream) const + { + aStream.WriteInt16L(TInt16(iIdentifier)); + aStream.WriteUint16L(iStartPosition); + aStream.WriteInt16L(iEncodedBodyLength); + + // Now create a buffer to hold the serialised body, and encode + HBufC8* buf = HBufC8::NewLC(SerialisedBodyLength()); + EncodeBodyL(buf->Des(), ETrue); + aStream << *buf; + CleanupStack::PopAndDestroy(buf); + } + +CEmsInformationElement* CEmsInformationElement::InternalizeL(RReadStream& aStream) + { + // Get the id and create the appropriate + TSmsId id; + id = TSmsId(aStream.ReadInt16L()); + CEmsInformationElement* elem = CEmsFactory::CreateIeL(id); + + if (!elem) + { + User::Leave(KErrCorrupt); + } + + CleanupStack::PushL(elem); + + // now stream into the new element + elem->iStartPosition = aStream.ReadUint16L(); + elem->iEncodedBodyLength = aStream.ReadInt16L(); + + // Create the buffer to hold the body data + HBufC8* buf = HBufC8::NewLC(aStream, elem->SerialisedBodyLength()); + elem->DecodeBodyL(buf->Des(), ETrue); + + CleanupStack::PopAndDestroy(buf); + CleanupStack::Pop(elem); + + return elem; + } + +void CEmsInformationElement::CopyL(const CEmsInformationElement& aSrc) + { + iIdentifier = aSrc.iIdentifier; + iStartPosition = aSrc.iStartPosition; + iEncodedBodyLength = aSrc.iEncodedBodyLength; + } + +TInt CEmsInformationElement::SerialisedBodyLength() const + { + // default behaviour for this is to return the encoded body length. + // This will be overriden by elements which differ (ie FormatIE) + return iEncodedBodyLength; + } + +/** + * Internalize all Ems Objects from a given stream. This is the flipside of the factorys + * externalise method. + * + * @param aStream stream to restore from. + * @return CEmsInformationElement* newly created EMS object. + */ + +/** + * Creates an information element from the data given + * + * @param aId EMS object id. + * @param aData Information Elements raw data. + * @return CEmsInformationElement* newly created EMS object. + */ +CEmsInformationElement* CEmsFactory::CreateIeL(TSmsId aSmsId) + { + CEmsInformationElement* pObj=NULL; + switch (aSmsId) + { + case CSmsInformationElement::ESmsEnhancedTextFormatting: + pObj = CEmsFormatIE::NewL(); + break; + case CSmsInformationElement::ESmsEnhancedPredefinedSound: + pObj = CEmsPreDefSoundIE::NewL(); + break; + case CSmsInformationElement::ESmsEnhancedUserDefinedSound: + pObj = CEmsSoundIE::NewL(); + break; + case CSmsInformationElement::ESmsEnhancedPredefinedAnimation: + pObj = CEmsPreDefAnimationIE::NewL(); + break; + case CSmsInformationElement::ESmsEnhancedLargeAnimation: + case CSmsInformationElement::ESmsEnhancedSmallAnimation: + pObj = CEmsAnimationIE::NewL(); + break; + case CSmsInformationElement::ESmsEnhancedLargePicture: + case CSmsInformationElement::ESmsEnhancedSmallPicture: + case CSmsInformationElement::ESmsEnhancedVariablePicture: + pObj = CEmsPictureIE::NewL(); + break; + case CSmsInformationElement::ESmsEnhancedUserPromptIndicator: + pObj = CEmsUserPrompt::NewL(); + break; + case CSmsInformationElement::ESmsEnhancedODI: + pObj = CEmsObjectDistribution::NewL(); + break; + default: + break; + } + if(pObj) + { + // set the id of the newly created EMS information element + pObj->iIdentifier = aSmsId; + } + return pObj; + } + +/** + * Externalises all the objects in a given object array. Adds extra information into externalised data + * so that objects can be readback generically (done this was as All streams do not support seek operatoions). + * This is the flipside of the Factorys internalise method. + * + * @param aObjectStore Array of objects to externalize. + * @param aStream stream to externalize object to. + */ +void CEmsFactory::ExternalizeL(RPointerArray& aObjectStore, RWriteStream& aStream) + { + TUint count= aObjectStore.Count(); + aStream.WriteUint32L(count); + for (TUint i=0; i< count; i++) + { + aObjectStore[i]->ExternalizeL(aStream); + } + } + +void CEmsFactory::InternalizeL(RPointerArray& aObjectStore, RReadStream& aStream) + { + // Retain store compat. with other Hur. 7 messaging stores. + TInt count=0; + TRAPD(test, count = aStream.ReadUint32L()); + if(test == KErrEof) + test=KErrNone; + User::LeaveIfError(test); + + CEmsInformationElement* ie = NULL; + + while(count--) + { + TRAPD(ret, (ie = CEmsInformationElement::InternalizeL(aStream))); + if(ret==KErrNone) + { + CleanupStack::PushL(ie); + User::LeaveIfError(aObjectStore.Append(ie)); + CleanupStack::Pop(ie); + } + else if(ret!=KErrCorrupt) + User::Leave(ret); + } + } + +CEmsInformationElement* CEmsFactory::CreateReceivedEmsIEL(const CSmsInformationElement& aIE,TInt aBaseAddr) + { + CEmsInformationElement* newIE = + CEmsInformationElement::DecodeInformationElementL(aIE); + + newIE->iStartPosition += aBaseAddr; + + return newIE; + } + + +TBool CEmsFactory::Supported(TSmsId aId) + { + TBool ret=ETrue; + switch (aId) + { + case CSmsInformationElement::ESmsEnhancedTextFormatting: + case CSmsInformationElement::ESmsEnhancedPredefinedSound: + case CSmsInformationElement::ESmsEnhancedUserDefinedSound: + case CSmsInformationElement::ESmsEnhancedPredefinedAnimation: + case CSmsInformationElement::ESmsEnhancedLargeAnimation: + case CSmsInformationElement::ESmsEnhancedSmallAnimation: + case CSmsInformationElement::ESmsEnhancedLargePicture: + case CSmsInformationElement::ESmsEnhancedSmallPicture: + case CSmsInformationElement::ESmsEnhancedVariablePicture: + case CSmsInformationElement::ESmsEnhancedUserPromptIndicator: + case CSmsInformationElement::ESmsEnhancedODI: + ret=ETrue; + break; + default: + ret=EFalse; + } + return ret; + }