smsprotocols/smsstack/ems/src/EMSInformationElement.cpp
changeset 0 3553901f7fa8
child 24 6638e7f4bd8f
equal deleted inserted replaced
-1:000000000000 0:3553901f7fa8
       
     1 /*
       
     2 * Copyright (c) 2009 Sony Ericsson Mobile Communications AB
       
     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 * Sony Ericsson Mobile Communications AB - initial contribution.
       
    11 * Nokia Corporation - additional changes.
       
    12 * 
       
    13 * Contributors:
       
    14 * 
       
    15 * Description:
       
    16 * Implements the Enhanced SMS Animation Information Element.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 /**
       
    22  *  @file
       
    23  *  
       
    24  *  Implements  EMSInformationElement class
       
    25  */
       
    26 
       
    27 #include <emsinformationelement.h>
       
    28 #include <emsformatie.h>
       
    29 #include <emssoundie.h>
       
    30 #include <emsanimationie.h>
       
    31 #include <emspictureie.h>
       
    32 #include <emsuserpromptie.h>
       
    33 #include <emsobjectdistributionie.h>
       
    34 
       
    35 
       
    36 EXPORT_C void CEmsInformationElement::SetStartPosition(TUint aValue)
       
    37 /**
       
    38  *  @capability None
       
    39  */
       
    40 	{
       
    41 	iStartPosition = aValue;
       
    42 	}
       
    43 
       
    44 EXPORT_C TUint CEmsInformationElement::StartPosition() const
       
    45 /**
       
    46  *  @capability None
       
    47  */
       
    48 	{
       
    49 	return iStartPosition;
       
    50 	}
       
    51 
       
    52 EXPORT_C TInt CEmsInformationElement::Length() const
       
    53 /**
       
    54  *  @capability None
       
    55  */
       
    56 	{
       
    57 	// The length includes the IE header (IEID, IEL) and the
       
    58 	// start position, if applicable, plus the encoded body length
       
    59 	TInt len = 2 + iEncodedBodyLength;
       
    60 	if (iStartPosEncoded)
       
    61 		{
       
    62 		++len;
       
    63 		}
       
    64 
       
    65 	return len;
       
    66 	}
       
    67 
       
    68 
       
    69 /**
       
    70  *  Encodes the EmsInformationElement into a CSmsInformationElement
       
    71  *  
       
    72  *  @param aSmsIe SMS information element to encode into
       
    73  */
       
    74 EXPORT_C void CEmsInformationElement::EncodeInformationElementL()
       
    75 /**
       
    76  *  @capability None
       
    77  */
       
    78 	{
       
    79 	TInt ieLength = iEncodedBodyLength;
       
    80 
       
    81 	// if start position is to be encoded, then increment this length
       
    82 	if (iStartPosEncoded)
       
    83 		{
       
    84 		++ieLength;
       
    85 		}
       
    86 
       
    87 	// Create a new body for the IE
       
    88 	NewDataL(ieLength);
       
    89 
       
    90 	// Get the raw data to be encoded
       
    91 	TPtr8 ptr(Data());
       
    92 	ptr.SetLength(0);
       
    93 
       
    94 	// Encode start position if required
       
    95 	if (iStartPosEncoded)
       
    96 		{
       
    97 		ptr.Append(static_cast<TUint8>(iStartPosition));
       
    98 		}
       
    99 
       
   100 	// Call the specific encode body function - false indicates NOT
       
   101 	// for serialisation
       
   102 	EncodeBodyL(ptr, EFalse);
       
   103 	}
       
   104 
       
   105 CEmsInformationElement* CEmsInformationElement::DecodeInformationElementL(const CSmsInformationElement& aSmsIe)
       
   106 	{
       
   107 	// Firstly, create the element given the ID
       
   108 	CEmsInformationElement* elem = CEmsFactory::CreateIeL(aSmsIe.Identifier());
       
   109 
       
   110 	if (!elem)
       
   111 		{
       
   112 		User::Leave(KErrCorrupt);
       
   113 		}
       
   114 
       
   115 	CleanupStack::PushL(elem);
       
   116 
       
   117 	// now decode the rest of the element
       
   118 	const TUint8* ptr;
       
   119 	const TDesC8& des = aSmsIe.Data();
       
   120 	TInt length = des.Length();
       
   121 
       
   122 	if (length <= 0)
       
   123 		User::Leave(KErrCorrupt);
       
   124 
       
   125 	// If the start position is encoded, then decode it, and add back
       
   126 	// in the start position offset
       
   127 	if (elem->iStartPosEncoded)
       
   128 		{
       
   129 		elem->iStartPosition = des[0];
       
   130 
       
   131 		// set the pointer to point to the first element, and
       
   132 		// reduce the length by 1;
       
   133 		ptr = &des[1];
       
   134 		--length;
       
   135 		}
       
   136 
       
   137 	else
       
   138 		{
       
   139 		// otherwise, set it to the first element
       
   140 		ptr = &des[0];
       
   141 		}
       
   142 
       
   143 	// set the encoded body length to be what's left over
       
   144 	elem->iEncodedBodyLength = length;
       
   145 
       
   146 	// Now call the specific decode body function.
       
   147 	elem->DecodeBodyL(TPtrC8(ptr, length), EFalse);
       
   148 
       
   149 	CleanupStack::Pop(elem);
       
   150 	return elem;
       
   151 	}
       
   152 
       
   153 void CEmsInformationElement::ExternalizeL(RWriteStream& aStream) const
       
   154 	{
       
   155 	aStream.WriteInt16L(TInt16(iIdentifier));
       
   156 	aStream.WriteUint16L(iStartPosition);
       
   157 	aStream.WriteInt16L(iEncodedBodyLength);
       
   158 
       
   159 	// Now create a buffer to hold the serialised body, and encode
       
   160 	HBufC8* buf = HBufC8::NewLC(SerialisedBodyLength());
       
   161 	EncodeBodyL(buf->Des(), ETrue);
       
   162 	aStream << *buf;
       
   163 	CleanupStack::PopAndDestroy(buf);
       
   164 	}
       
   165 
       
   166 CEmsInformationElement* CEmsInformationElement::InternalizeL(RReadStream& aStream)
       
   167 	{
       
   168 	// Get the id and create the appropriate
       
   169 	TSmsId id;
       
   170 	id = TSmsId(aStream.ReadInt16L());
       
   171 	CEmsInformationElement* elem = CEmsFactory::CreateIeL(id);
       
   172 
       
   173 	if (!elem)
       
   174 		{
       
   175 		User::Leave(KErrCorrupt);
       
   176 		}
       
   177 
       
   178 	CleanupStack::PushL(elem);
       
   179 
       
   180 	// now stream into the new element
       
   181 	elem->iStartPosition = aStream.ReadUint16L();
       
   182 	elem->iEncodedBodyLength = aStream.ReadInt16L();
       
   183 
       
   184 	// Create the buffer to hold the body data
       
   185 	HBufC8* buf = HBufC8::NewLC(aStream, elem->SerialisedBodyLength());
       
   186 	elem->DecodeBodyL(buf->Des(), ETrue);
       
   187 
       
   188 	CleanupStack::PopAndDestroy(buf);
       
   189 	CleanupStack::Pop(elem);
       
   190 
       
   191 	return elem;
       
   192 	}
       
   193 
       
   194 void CEmsInformationElement::CopyL(const CEmsInformationElement& aSrc)
       
   195 	{
       
   196 	iIdentifier = aSrc.iIdentifier;
       
   197 	iStartPosition = aSrc.iStartPosition;
       
   198 	iEncodedBodyLength = aSrc.iEncodedBodyLength;
       
   199 	}
       
   200 
       
   201 TInt CEmsInformationElement::SerialisedBodyLength() const
       
   202 	{
       
   203 	// default behaviour for this is to return the encoded body length.
       
   204 	// This will be overriden by elements which differ (ie FormatIE)
       
   205 	return iEncodedBodyLength;
       
   206 	}
       
   207 
       
   208 /**
       
   209  *  Internalize all Ems Objects from a given stream. This is the flipside of the factorys
       
   210  *  externalise method.
       
   211  *  
       
   212  *  @param aStream stream to restore from.
       
   213  *  @return CEmsInformationElement* newly created EMS object.
       
   214  */
       
   215 
       
   216 /**
       
   217  *  Creates an information element from the data given
       
   218  *  
       
   219  *  @param aId EMS object id.
       
   220  *  @param aData Information Elements raw data.
       
   221  *  @return CEmsInformationElement* newly created EMS object.
       
   222  */
       
   223 CEmsInformationElement* CEmsFactory::CreateIeL(TSmsId aSmsId)
       
   224 	{
       
   225 	CEmsInformationElement* pObj=NULL;
       
   226 	switch (aSmsId)
       
   227 		{
       
   228 		case CSmsInformationElement::ESmsEnhancedTextFormatting:
       
   229 			pObj = CEmsFormatIE::NewL();
       
   230 			break;
       
   231 		case CSmsInformationElement::ESmsEnhancedPredefinedSound:
       
   232 			pObj = CEmsPreDefSoundIE::NewL();
       
   233 			break;
       
   234 		case CSmsInformationElement::ESmsEnhancedUserDefinedSound:
       
   235 			pObj = CEmsSoundIE::NewL();
       
   236 			break;
       
   237 		case CSmsInformationElement::ESmsEnhancedPredefinedAnimation:
       
   238 			pObj = CEmsPreDefAnimationIE::NewL();
       
   239 			break;
       
   240 		case CSmsInformationElement::ESmsEnhancedLargeAnimation:
       
   241 		case CSmsInformationElement::ESmsEnhancedSmallAnimation:
       
   242 			pObj = CEmsAnimationIE::NewL();
       
   243 			break;
       
   244 		case CSmsInformationElement::ESmsEnhancedLargePicture:
       
   245 		case CSmsInformationElement::ESmsEnhancedSmallPicture:
       
   246 		case CSmsInformationElement::ESmsEnhancedVariablePicture:
       
   247 			pObj = CEmsPictureIE::NewL();
       
   248 			break;
       
   249 		case CSmsInformationElement::ESmsEnhancedUserPromptIndicator:
       
   250 			pObj = CEmsUserPrompt::NewL();
       
   251 			break;
       
   252 		case CSmsInformationElement::ESmsEnhancedODI:
       
   253 			pObj = CEmsObjectDistribution::NewL();
       
   254 			break;
       
   255 		default:
       
   256 			break;
       
   257 		}
       
   258 	if(pObj)
       
   259 		{
       
   260 		// set the id of the newly created EMS information element
       
   261 		pObj->iIdentifier = aSmsId;
       
   262 		}
       
   263 	return pObj;
       
   264 	}
       
   265 
       
   266 /**
       
   267  *  Externalises all the objects in a given object array. Adds extra information into externalised data
       
   268  *  so that objects can be readback generically (done this was as All streams do not support seek operatoions).
       
   269  *  This is the flipside of the Factorys internalise method.
       
   270  *  
       
   271  *  @param aObjectStore Array of objects to externalize.
       
   272  *  @param aStream stream to externalize object to.
       
   273  */
       
   274 void CEmsFactory::ExternalizeL(RPointerArray<CEmsInformationElement>& aObjectStore, RWriteStream& aStream)
       
   275 	{
       
   276 	TUint count= aObjectStore.Count();
       
   277 	aStream.WriteUint32L(count);
       
   278 	for (TUint i=0; i< count; i++)
       
   279 		{
       
   280 		aObjectStore[i]->ExternalizeL(aStream);
       
   281 		}
       
   282 	}
       
   283 
       
   284 void CEmsFactory::InternalizeL(RPointerArray<CEmsInformationElement>& aObjectStore, RReadStream& aStream)
       
   285 	{
       
   286 	// Retain store compat. with other Hur. 7 messaging stores.
       
   287 	TInt count=0;
       
   288 	TRAPD(test, count = aStream.ReadUint32L());
       
   289 	if(test == KErrEof)
       
   290 		test=KErrNone;
       
   291 	User::LeaveIfError(test);
       
   292 
       
   293 	CEmsInformationElement* ie = NULL;
       
   294 
       
   295 	while(count--)
       
   296 		{
       
   297 		TRAPD(ret, (ie = CEmsInformationElement::InternalizeL(aStream)));
       
   298 		if(ret==KErrNone)
       
   299 			{
       
   300 			CleanupStack::PushL(ie);
       
   301 			User::LeaveIfError(aObjectStore.Append(ie));
       
   302 			CleanupStack::Pop(ie);
       
   303 			}
       
   304 		else if(ret!=KErrCorrupt)
       
   305 			User::Leave(ret);
       
   306 		}
       
   307 	}
       
   308 
       
   309 CEmsInformationElement* CEmsFactory::CreateReceivedEmsIEL(const CSmsInformationElement& aIE,TInt aBaseAddr)
       
   310 	{
       
   311 	CEmsInformationElement* newIE =
       
   312 		CEmsInformationElement::DecodeInformationElementL(aIE);
       
   313 
       
   314 	newIE->iStartPosition += aBaseAddr;
       
   315 
       
   316 	return newIE;
       
   317 	}
       
   318 
       
   319 
       
   320 TBool CEmsFactory::Supported(TSmsId aId)
       
   321 	{
       
   322 	TBool ret=ETrue;
       
   323 	switch (aId)
       
   324 		{
       
   325 	case CSmsInformationElement::ESmsEnhancedTextFormatting:
       
   326 	case CSmsInformationElement::ESmsEnhancedPredefinedSound:
       
   327 	case CSmsInformationElement::ESmsEnhancedUserDefinedSound:
       
   328 	case CSmsInformationElement::ESmsEnhancedPredefinedAnimation:
       
   329 	case CSmsInformationElement::ESmsEnhancedLargeAnimation:
       
   330 	case CSmsInformationElement::ESmsEnhancedSmallAnimation:
       
   331 	case CSmsInformationElement::ESmsEnhancedLargePicture:
       
   332 	case CSmsInformationElement::ESmsEnhancedSmallPicture:
       
   333 	case CSmsInformationElement::ESmsEnhancedVariablePicture:
       
   334 	case CSmsInformationElement::ESmsEnhancedUserPromptIndicator:
       
   335 	case CSmsInformationElement::ESmsEnhancedODI:
       
   336 		ret=ETrue;
       
   337 		break;
       
   338 	default:
       
   339 		ret=EFalse;
       
   340 		}
       
   341 	return ret;
       
   342 	}