sl@0: // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #include <wspencoder.h>
sl@0: 
sl@0: //constants
sl@0: //
sl@0: const TUint8 KWSPQuoteCharacter	= 0x7F; // QUOTE character as specified in the WSP BNF. 
sl@0: const TUint8 KWSPQuote			= 0x22; // The regular quote character ".
sl@0: const TUint8 KCarryBitMask		= 0x80; // Continue bit set
sl@0: #define KTopBitMask KCarryBitMask		// Mask for checking top bit
sl@0: const TUint KUintVarIndicator	= 31;	// Byte value indicating a UIntVar follows.
sl@0: const TUint KUIntVarOctetShift	= 7;	// Octet shift required processing a UnIntVar
sl@0: const TUint KLongIntOctetShift	= 8;	// Octet shift required processing a LongInt
sl@0: const TInt KDesArrayGranularity = 6;	// Granularity of descriptor array
sl@0: _LIT8(KWspStringTerminator, "\0");
sl@0: _LIT8(KTxtSeparators, "()<>@,;:\\\"/[]?={} "); // Separator characters as defined in RFC2616
sl@0: 
sl@0: // Panic category
sl@0: //
sl@0: _LIT(KWspCodecPanicCategory,"WSPCODEC"); 
sl@0: 
sl@0: /**
sl@0: 	Static factory constructor.
sl@0: 	
sl@0: 	@leave			KErrNoMemory
sl@0: 	@return		returns a Pointer to fully constructed CWspHeaderEncoder object.
sl@0: */
sl@0: EXPORT_C CWspHeaderEncoder* CWspHeaderEncoder::NewL()
sl@0: 	{
sl@0: 	CWspHeaderEncoder* self = CWspHeaderEncoder::NewLC();
sl@0: 	CleanupStack::Pop(self);
sl@0: 	return self;
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:  	Static factory constructor.
sl@0: 	
sl@0: 	@leave			KErrNoMemory
sl@0: 	@return		returns a Pointer to fully constructed CWspHeaderEncoder object on the Heap.
sl@0: */
sl@0: EXPORT_C CWspHeaderEncoder* CWspHeaderEncoder::NewLC()
sl@0: 	{
sl@0: 	CWspHeaderEncoder* self = new (ELeave) CWspHeaderEncoder();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL();
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: /** 
sl@0: 	Default constructor. 
sl@0: */
sl@0: CWspHeaderEncoder::CWspHeaderEncoder()
sl@0: 	{
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0: 	 Default destructor
sl@0: */
sl@0: EXPORT_C CWspHeaderEncoder::~CWspHeaderEncoder()			
sl@0: 	{
sl@0: 	iArray.ResetAndDestroy();
sl@0: 	}
sl@0: 
sl@0: /** 
sl@0: 	Standard second phase construction. 
sl@0: */
sl@0: void CWspHeaderEncoder::ConstructL()			
sl@0: 	{
sl@0: 	// Create new buffer;
sl@0: 	CDesC8Array* buffer = new (ELeave) CDesC8ArrayFlat(KDesArrayGranularity);
sl@0: 	CleanupStack::PushL(buffer);
sl@0: 	User::LeaveIfError(iArray.Append(buffer));
sl@0: 	CleanupStack::Pop(buffer);
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:   Starts a new encoded header. 
sl@0:  
sl@0:   @param 			aToken	field name being encoded as a Token value.
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::StartHeaderL(TUint8 aToken)			
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
sl@0: 	AddShortIntL(aToken);
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:   Starts a new encoded header.
sl@0: 
sl@0:   @param 	aString	Fieldname parameter is encoded as a TextString.
sl@0:   @leave	KErrNoMemory
sl@0: */	
sl@0: EXPORT_C void CWspHeaderEncoder::StartHeaderL(const TDesC8& aString)
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
sl@0: 	AddTextStringL(aString);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Starts a new encoded header.
sl@0: 
sl@0:   @param 	aString	Fieldname parameter is encoded as a TextString.
sl@0:   @leave	KErrNotSupported
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::StartHeaderL(const RStringF /* aString */ )
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
sl@0: 	User::Leave(KErrNotSupported);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0:  	Completes and returns encoded field 8 bit buffer. This method will panic if an 
sl@0:  	EndValueLengthL() is not called after a StartValueLength().
sl@0: 	
sl@0: 	Note: 
sl@0: 	The final buffer containing the entire encoded header is constructed.
sl@0: 	Returns buffer containing the encoded field constructed 
sl@0: 	from the first call to StartHeaderL. 
sl@0: 					
sl@0: 	@return		Pointer to buffer containing the entire encoded field.
sl@0: 	 			Responsibility for deallocating the memory is also passed.
sl@0: 	@pre 		The function StartHeaderL should have been called.
sl@0: 	@post		Encoder is reset ready to be used again.
sl@0: 	@leave		HBufC8::NewL leaves, if the new 8 bit heap descriptor cannot be created.
sl@0: 
sl@0: */
sl@0: EXPORT_C HBufC8* CWspHeaderEncoder::EndHeaderL()
sl@0: 	{
sl@0: 	__ASSERT_DEBUG(iArray.Count()==1,User::Panic(KWspCodecPanicCategory, EWspCodecPanicEndValueLengthNotCalled));
sl@0: 	// concatenate array elements and return.
sl@0: 
sl@0: 	HBufC8* outputBuffer = HBufC8::NewL(iTotalLength);
sl@0: 
sl@0: 	CDesC8Array* desc = iArray[0];
sl@0: 	TInt count = desc->Count();
sl@0: 	for (TInt jj=0; jj<count; ++jj) 
sl@0: 		{
sl@0: 		(outputBuffer->Des()).Append((*desc)[jj]);
sl@0: 		}
sl@0: 
sl@0: 	desc->Reset();
sl@0: 	iTotalLength=0;
sl@0: 	return outputBuffer;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Encodes input Integer value and adds it to the encoded field. Choice of encoded 
sl@0:   form dependent on the size of the input.Either ShortInt or LongInt method chosen.
sl@0: 					
sl@0:   @param 		aInt	Integer value to be encoded.
sl@0:   @pre			StartHeaderL needs to have been called.
sl@0:   @leave		KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddIntegerL(const TUint aInt)
sl@0: 	{
sl@0: 	// Determine if its a short or longInt we want
sl@0: 	(aInt < KTopBitMask) ? AddShortIntL((TUint8) aInt) : AddLongIntL(aInt);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. Encodes parameter value using WSP 
sl@0:   ShortInt method.
sl@0:  					
sl@0:   @param 			aValue	value to be encoded.
sl@0:   @pre				StartHeaderL needs to have been called.
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddShortIntL(const TUint8 aValue)
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 
sl@0: 
sl@0: 	// ShortInt shoud be a character 127 or less. With highest bit set to 1.
sl@0: 	TUint8 shortInt = TWspPrimitiveEncoder::ShortInt(aValue);
sl@0: 
sl@0: 	desc->AppendL(TPtrC8(&shortInt, 1));
sl@0: 	++iTotalLength;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. For short length the value must
sl@0:   be between octet 0 - 31.
sl@0:  	
sl@0:   @param 		aValue	value to be encoded.
sl@0:   @pre			StartHeaderL needs to have been called.
sl@0:   @leave		KErrNoMemory, KErrOverflow if the value is greater than 31
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddShortLengthL(const TUint8 aValue)
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 
sl@0: 	// Check if the value is in the correct range ie octet 0-31
sl@0: 	if(aValue > KUintVarIndicator)
sl@0: 		User::Leave(KErrOverflow);
sl@0: 
sl@0: 	desc->AppendL(TPtrC8(&aValue, 1));
sl@0: 	++iTotalLength;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. Encodes parameter value using WSP 
sl@0:   LongInt method.
sl@0:  					
sl@0:   @param 			aValue	value to be encoded.
sl@0:   @pre				StartHeaderL needs to have been called.
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddLongIntL(const TUint32 aValue)
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 
sl@0: 	HBufC8* buf = TWspPrimitiveEncoder::LongIntL(aValue);
sl@0: 	CleanupStack::PushL(buf);
sl@0: 
sl@0: 	desc->AppendL(*buf);
sl@0: 	iTotalLength+=buf->Length();
sl@0: 
sl@0: 	CleanupStack::PopAndDestroy(buf);
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. Encodes parameter value using WSP 
sl@0:   UIntVar method.
sl@0:  					
sl@0:   @param 		aInt	value to be encoded.
sl@0:   @pre			StartHeaderL needs to have been called.
sl@0:   @leave		KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddUintVarL(const TUint aInt)
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 
sl@0: 	HBufC8*	buf = TWspPrimitiveEncoder::UintVarL(aInt);
sl@0: 	CleanupStack::PushL(buf);
sl@0: 
sl@0: 	desc->AppendL(*buf);
sl@0: 	iTotalLength+=buf->Length();
sl@0: 
sl@0: 	CleanupStack::PopAndDestroy(buf);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. Encodes parameter value using WSP
sl@0:   TextString method.
sl@0:  				   
sl@0:   @param 			aText		value to be encoded.
sl@0:   @pre				StartHeaderL needs to have been called.
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddTextStringL(const TDesC8& aText)
sl@0: 	{	
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 
sl@0: 	HBufC8*	buf = TWspPrimitiveEncoder::TextStringL(aText);
sl@0: 	CleanupStack::PushL(buf);
sl@0: 	desc->AppendL(*buf);
sl@0: 	iTotalLength+=buf->Length();
sl@0: 	CleanupStack::PopAndDestroy(buf);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. Encodes parameter value using WSP
sl@0:   TextString method.
sl@0:   	   	
sl@0:   @param 			aText		value to be encoded.
sl@0:   @pre				StartHeaderL needs to have been called.
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddTextStringL(const RString& /* aText */)
sl@0: 	{
sl@0: 	User::Leave(KErrNotSupported);
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field.Encodes parameter value using WSP 
sl@0:   Date method.
sl@0:  				   
sl@0:   @param 			aDate		value to be encoded.
sl@0:   @pre				StartHeaderL needs to have been called.
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddDateL(const TDateTime aDate)
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 
sl@0: 	HBufC8* buf = TWspPrimitiveEncoder::DateL(aDate);
sl@0: 	CleanupStack::PushL(buf);
sl@0: 	desc->AppendL(*buf);
sl@0: 	iTotalLength+=buf->Length();
sl@0: 	CleanupStack::PopAndDestroy(buf);
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. Adds value as-is to the encoded field.
sl@0:  				   
sl@0:   @param 	aToken	parameter added without encodeing. Should be a valid WSP token, 
sl@0:   a 8 bit number > 0x7F (i.e. top bit set).
sl@0:   @pre 		StartHeaderL and StartValueLengthL should have been called.
sl@0:   @post		EndValueLengthL needs to be called subsequently.
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddTokenL(const TUint8 aToken)
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 
sl@0: 	TUint8 shortInt = (TUint8) (aToken); 
sl@0: 	desc->AppendL(TPtrC8(&shortInt, 1));
sl@0: 	++iTotalLength;
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. Encodes parameter value using WSP 
sl@0:   TokenText method.
sl@0:  				  
sl@0:   @param 		aTokenText	value to be encoded.
sl@0:   @leave		KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddTokenTextL(const TDesC8& aTokenText)
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 
sl@0: 	// Step through token text passed in and ensure there are no invalid characters
sl@0: 	const TInt tokenTextLength = aTokenText.Length();
sl@0: 	for( TInt ii = 0; ii<tokenTextLength; ++ii)
sl@0: 		{
sl@0: 		TUint8 currentChar = aTokenText[ii];
sl@0: 		if( KTxtSeparators().Locate(currentChar) != KErrNotFound )
sl@0: 			User::Leave(KErrCorrupt);
sl@0: 		}
sl@0: 	// Token text does not contain any invalid characters
sl@0: 	HBufC8* buf = TWspPrimitiveEncoder::TextStringL(aTokenText);
sl@0: 	CleanupStack::PushL(buf);
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 	desc->AppendL(*buf);
sl@0: 	iTotalLength += buf->Length();
sl@0: 	CleanupStack::PopAndDestroy(buf);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Encodes input and adds it to the encoded field. Adds value as-is to the encoded field.
sl@0:  					
sl@0:   @param 			aData		value to be encoded.
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::AddDataL(const TDesC8& aData)
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1];
sl@0: 	desc->AppendL(aData);
sl@0: 	iTotalLength += aData.Length();
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   From calling this function, the length in bytes of all encodings added subsequently will
sl@0:   be calculated and stored as part of the encoded string, as specified in WSP spec.Can be nested. i.e.
sl@0:   @code
sl@0: 	 encoder->StartHeaderL();
sl@0: 	 encoder->StartValueLengthL();
sl@0: 	 encoder->StartValueLengthL();
sl@0: 	 encoder->AddLongIntL();
sl@0: 	 encoder->EndValueLengthL();
sl@0: 	 encoder->AddTextStringL();
sl@0: 	 encoder->EndValueLengthL();
sl@0: 	 HBufC8* output = encoder->EndHeaderL();
sl@0:   @endcode
sl@0:  	
sl@0:   @pre 			StartHeaderL should have been called.
sl@0:   @post			EndValueLengthL needs to be called subsequently.
sl@0:   @leave		KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::StartValueLengthL()
sl@0: 	{
sl@0: 	// Create new buffer;
sl@0: 	CDesC8Array* buffer = new (ELeave) CDesC8ArrayFlat(KDesArrayGranularity);
sl@0: 	CleanupStack::PushL(buffer);
sl@0: 	User::LeaveIfError(iArray.Append(buffer));
sl@0: 	CleanupStack::Pop(buffer);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Needs to be called at the point in the construction of a header when ValueLength 
sl@0:   can be calculated.
sl@0:  					  
sl@0:   @pre 			StartHeaderL and StartValueLengthL should have been called.
sl@0:   @post			ValueLength has been calculated and added, together with the
sl@0:  				encoded header, to the internal representation of the header buffer.
sl@0:   @leave		KErrNoMemory
sl@0: */
sl@0: EXPORT_C void CWspHeaderEncoder::EndValueLengthL()
sl@0: 	{
sl@0: 	const TInt arrayCount=iArray.Count();
sl@0: 	__ASSERT_ALWAYS(arrayCount>1,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartValueLengthNotCalled));
sl@0: 
sl@0: 	// Calculate the length of the current buffer.
sl@0: 	// and append it onto the previous buffer. [length value, then data]
sl@0: 	TUint32 valueLength=0;
sl@0: 
sl@0: 
sl@0: 	CDesC8Array* desc=iArray[arrayCount-1]; // current descriptor being dealt with
sl@0: 	CDesC8Array* parentDesc=iArray[arrayCount-2]; // parent descriptor to which it must be added.
sl@0: 
sl@0: 	TInt buffersToAdd=desc->Count();
sl@0: 	TInt ii=buffersToAdd;
sl@0: 
sl@0: 	// Check the length of all parameters (not the first element in tha array, the field name)
sl@0: 	while (ii)
sl@0: 		valueLength+=(*desc)[--ii].Length();
sl@0: 	
sl@0: 	// Remove desc from array. Will have to delete also.
sl@0: 	iArray.Remove(arrayCount-1);
sl@0: 	CleanupStack::PushL(desc);
sl@0: 
sl@0: 	// Depending of size of the length save as number or UintVar
sl@0: 	if (valueLength < KUintVarIndicator)
sl@0: 		{
sl@0: 		// Value length represented by an 8 bit number.
sl@0: 		AddShortLengthL( (TUint8) valueLength);
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		// Value length represented by an 8bit value indicating a UIntVar follows,
sl@0: 		// followed by a UIntVar
sl@0: 		AddShortLengthL( (TUint8) KUintVarIndicator);
sl@0: 		AddUintVarL(valueLength);
sl@0: 		}
sl@0: 
sl@0: 	// Add field value, parameters etc.
sl@0: 	ii=0;
sl@0: 	while (ii<buffersToAdd)
sl@0: 		parentDesc->AppendL((*desc)[ii++]);
sl@0: 
sl@0: 	CleanupStack::PopAndDestroy(desc);
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: 
sl@0: //**********************************************************************************
sl@0: 
sl@0: /**
sl@0:   Takes a TUint8 parameter, and sets the top bit. As specified for the WSP ShortInt 
sl@0:   encoding method.
sl@0:  					
sl@0:   @param 		aValue number to be encoded.
sl@0:   @return 		Output, encoded as a TUint8, representation of the header buffer.
sl@0:  				If input greater that 127 (invalid input), returns 0
sl@0: */
sl@0: EXPORT_C TUint8 TWspPrimitiveEncoder::ShortInt(const TUint8 aValue)
sl@0: 	{
sl@0: 	// ShortInt should be a character 127 or less. With highest bit set to 1.
sl@0: 	return (aValue > KWSPQuoteCharacter) ? (TUint8) 0: (TUint8) (aValue | KTopBitMask); 
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Takes a TUint32 parameter and encodes it using the WSP specified LongInt method.
sl@0:   	
sl@0:   @param 			aValue number to be encoded.
sl@0:   @return 			Output, encoded HBufC8 buffer. 
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C HBufC8* TWspPrimitiveEncoder::LongIntL(const TUint32 aValue)
sl@0: 	{
sl@0: 	// Consists of size and up to number of 30 bytes.
sl@0: 	// for a TInt32 the maximum is 4 bytes long.
sl@0: 	// Check size of number, to determine number of bytes needed to store it.
sl@0: 
sl@0: 	TUint8 size = 0; // maximum value is 4 with a 32bit integer
sl@0: 	TUint32 value=aValue;
sl@0: 	do {
sl@0: 		++size;
sl@0: 		value >>=KLongIntOctetShift; ; // shift by 8 bits.
sl@0: 		} while (value>0);
sl@0: 
sl@0: 	HBufC8* output = HBufC8::NewL(size+1);
sl@0: 	TPtr8 outPtr(output->Des());
sl@0: 
sl@0: 	outPtr.Append(size);
sl@0: 	TInt ii = size;
sl@0: 	while (ii-- >0) 
sl@0: 		{		
sl@0: 		outPtr.Append( (TUint8) (aValue>>ii*KLongIntOctetShift) );
sl@0: 		}
sl@0: 
sl@0: 	return output;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Takes a TUint32 parameter and encodes it using the WSP specified UintVar method.
sl@0:   					
sl@0:   @param 			aInt number to be encoded.
sl@0:   @return 			Output, encoded HBufC8 buffer. 
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C HBufC8* TWspPrimitiveEncoder::UintVarL(const TUint32 aInt)
sl@0: 	{
sl@0: 	TUint8 size = 0; // maximum value is 5 with a 32bit integer
sl@0: 	TUint32 value=aInt;
sl@0: 	do {
sl@0: 		++size;
sl@0: 		value >>=KUIntVarOctetShift; ; // shift by 7 bits.
sl@0: 		} while (value>0);
sl@0: 
sl@0: 	HBufC8* output = HBufC8::NewL(size);
sl@0: 	TPtr8 outPtr(output->Des());
sl@0: 
sl@0: 	TInt ii = size; 
sl@0: 	while (--ii > 0)
sl@0: 		{
sl@0: 		outPtr.Append( (TUint8)(aInt>>(KUIntVarOctetShift*(ii))  & KWSPQuoteCharacter) | KCarryBitMask); 
sl@0: 		} 
sl@0: 
sl@0: 	// Finally the first 7 bits, last octet, do not set first bit.
sl@0: 	outPtr.Append( (TUint8)(aInt & KWSPQuoteCharacter) ); // Add even if 0 value.
sl@0: 
sl@0: 	return output;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Takes a RString parameter and encodes it using the WSP specified TextString method.
sl@0:   					
sl@0:   @param 			aText string to be encoded.
sl@0:   @return 			Output, encoded HBufC8 buffer. 
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C HBufC8* TWspPrimitiveEncoder::TextStringL(const RString  /* aText*/ )
sl@0: 	{
sl@0: 	User::Leave(KErrNotSupported);
sl@0: 	return NULL;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Takes a TDesC8 parameter and encodes it using the WSP specified TextString method.
sl@0:   					
sl@0:   @param 			aText string to be encoded.
sl@0:   @return 			Output, encoded HBufC8 buffer. 
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C HBufC8* TWspPrimitiveEncoder::TextStringL(const TDesC8& aText)
sl@0: 	{
sl@0: 	HBufC8* output=NULL;
sl@0: 	TInt stringLength = aText.Length();
sl@0: 	TUint8 firstChar = 0;
sl@0: 	TUint8 lastChar = 0;
sl@0: 	if(stringLength>0)
sl@0: 		{
sl@0: 		firstChar = aText[0];
sl@0: 		lastChar = aText[stringLength-1];
sl@0: 		}
sl@0: 
sl@0: 	TPtr8 outPtr(NULL,0);
sl@0: 	if (firstChar > KWSPQuoteCharacter)
sl@0: 		{
sl@0: 		// Apply WSP rule: first character of the string not 7bit add QuoteCharacter.
sl@0: 		// Add the quote character and include space for the NULL character
sl@0: 		stringLength+=2;
sl@0: 		output =  HBufC8::NewL(stringLength); 
sl@0: 		outPtr.Set(output->Des());
sl@0: 
sl@0: 		outPtr.Append(KWSPQuoteCharacter);
sl@0: 		outPtr.Append(aText);
sl@0: 		}
sl@0: 	else if (firstChar==KWSPQuote && lastChar==KWSPQuote)
sl@0: 		{
sl@0: 		// Apply WSP rule: if quoted string, remove the closing quote
sl@0: 		output =  HBufC8::NewL(stringLength); 
sl@0: 		outPtr.Set(output->Des());
sl@0: 		outPtr.Append(aText);
sl@0: 		outPtr.SetLength(stringLength-1);
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		stringLength+=1; // terminating NULL char
sl@0: 		output =  HBufC8::NewL(stringLength); 
sl@0: 		outPtr.Set(output->Des());
sl@0: 		outPtr.Append(aText);
sl@0: 		}
sl@0: 
sl@0: 	// Terminate string with 0x00
sl@0: 	outPtr.Append(KWspStringTerminator);
sl@0: 	return output;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:   Takes a TDateTime parameter and encodes it using the WSP specified Date encoding method.
sl@0:   
sl@0:   @param 			aDate value to be encoded.
sl@0:   @return 			Output, encoded HBufC8 buffer. 
sl@0:   @leave			KErrNoMemory
sl@0: */
sl@0: EXPORT_C HBufC8* TWspPrimitiveEncoder::DateL(const TDateTime aDate)
sl@0: 	{
sl@0: 	TTime baseTime(TDateTime(1970,EJanuary,0,0,0,0,0));
sl@0: 	TTime dateTime(aDate);
sl@0: 	TTimeIntervalSeconds interval;
sl@0: 	dateTime.SecondsFrom(baseTime, interval);
sl@0: 
sl@0: 	return LongIntL(interval.Int());
sl@0: 	}
sl@0: