--- /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 <emsinformationelement.h>
+#include <emsformatie.h>
+#include <emssoundie.h>
+#include <emsanimationie.h>
+#include <emspictureie.h>
+#include <emsuserpromptie.h>
+#include <emsobjectdistributionie.h>
+
+
+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<TUint8>(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<CEmsInformationElement>& 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<CEmsInformationElement>& 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;
+ }