genericservices/httputils/wspcodec/WSPEncoder.cpp
changeset 0 e4d67989cc36
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <wspencoder.h>
       
    17 
       
    18 //constants
       
    19 //
       
    20 const TUint8 KWSPQuoteCharacter	= 0x7F; // QUOTE character as specified in the WSP BNF. 
       
    21 const TUint8 KWSPQuote			= 0x22; // The regular quote character ".
       
    22 const TUint8 KCarryBitMask		= 0x80; // Continue bit set
       
    23 #define KTopBitMask KCarryBitMask		// Mask for checking top bit
       
    24 const TUint KUintVarIndicator	= 31;	// Byte value indicating a UIntVar follows.
       
    25 const TUint KUIntVarOctetShift	= 7;	// Octet shift required processing a UnIntVar
       
    26 const TUint KLongIntOctetShift	= 8;	// Octet shift required processing a LongInt
       
    27 const TInt KDesArrayGranularity = 6;	// Granularity of descriptor array
       
    28 _LIT8(KWspStringTerminator, "\0");
       
    29 _LIT8(KTxtSeparators, "()<>@,;:\\\"/[]?={} "); // Separator characters as defined in RFC2616
       
    30 
       
    31 // Panic category
       
    32 //
       
    33 _LIT(KWspCodecPanicCategory,"WSPCODEC"); 
       
    34 
       
    35 /**
       
    36 	Static factory constructor.
       
    37 	
       
    38 	@leave			KErrNoMemory
       
    39 	@return		returns a Pointer to fully constructed CWspHeaderEncoder object.
       
    40 */
       
    41 EXPORT_C CWspHeaderEncoder* CWspHeaderEncoder::NewL()
       
    42 	{
       
    43 	CWspHeaderEncoder* self = CWspHeaderEncoder::NewLC();
       
    44 	CleanupStack::Pop(self);
       
    45 	return self;
       
    46 	}
       
    47 	
       
    48 /**
       
    49  	Static factory constructor.
       
    50 	
       
    51 	@leave			KErrNoMemory
       
    52 	@return		returns a Pointer to fully constructed CWspHeaderEncoder object on the Heap.
       
    53 */
       
    54 EXPORT_C CWspHeaderEncoder* CWspHeaderEncoder::NewLC()
       
    55 	{
       
    56 	CWspHeaderEncoder* self = new (ELeave) CWspHeaderEncoder();
       
    57 	CleanupStack::PushL(self);
       
    58 	self->ConstructL();
       
    59 	return self;
       
    60 	}
       
    61 
       
    62 /** 
       
    63 	Default constructor. 
       
    64 */
       
    65 CWspHeaderEncoder::CWspHeaderEncoder()
       
    66 	{
       
    67 	}
       
    68 	
       
    69 /**
       
    70 	 Default destructor
       
    71 */
       
    72 EXPORT_C CWspHeaderEncoder::~CWspHeaderEncoder()			
       
    73 	{
       
    74 	iArray.ResetAndDestroy();
       
    75 	}
       
    76 
       
    77 /** 
       
    78 	Standard second phase construction. 
       
    79 */
       
    80 void CWspHeaderEncoder::ConstructL()			
       
    81 	{
       
    82 	// Create new buffer;
       
    83 	CDesC8Array* buffer = new (ELeave) CDesC8ArrayFlat(KDesArrayGranularity);
       
    84 	CleanupStack::PushL(buffer);
       
    85 	User::LeaveIfError(iArray.Append(buffer));
       
    86 	CleanupStack::Pop(buffer);
       
    87 	}
       
    88 	
       
    89 /**
       
    90   Starts a new encoded header. 
       
    91  
       
    92   @param 			aToken	field name being encoded as a Token value.
       
    93   @leave			KErrNoMemory
       
    94 */
       
    95 EXPORT_C void CWspHeaderEncoder::StartHeaderL(TUint8 aToken)			
       
    96 	{
       
    97 	__ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
       
    98 	AddShortIntL(aToken);
       
    99 	}
       
   100 	
       
   101 /**
       
   102   Starts a new encoded header.
       
   103 
       
   104   @param 	aString	Fieldname parameter is encoded as a TextString.
       
   105   @leave	KErrNoMemory
       
   106 */	
       
   107 EXPORT_C void CWspHeaderEncoder::StartHeaderL(const TDesC8& aString)
       
   108 	{
       
   109 	__ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
       
   110 	AddTextStringL(aString);
       
   111 	}
       
   112 
       
   113 /**
       
   114   Starts a new encoded header.
       
   115 
       
   116   @param 	aString	Fieldname parameter is encoded as a TextString.
       
   117   @leave	KErrNotSupported
       
   118 */
       
   119 EXPORT_C void CWspHeaderEncoder::StartHeaderL(const RStringF /* aString */ )
       
   120 	{
       
   121 	__ASSERT_DEBUG(iTotalLength==0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderCalledTwice));
       
   122 	User::Leave(KErrNotSupported);
       
   123 	}
       
   124 
       
   125 
       
   126 /**
       
   127  	Completes and returns encoded field 8 bit buffer. This method will panic if an 
       
   128  	EndValueLengthL() is not called after a StartValueLength().
       
   129 	
       
   130 	Note: 
       
   131 	The final buffer containing the entire encoded header is constructed.
       
   132 	Returns buffer containing the encoded field constructed 
       
   133 	from the first call to StartHeaderL. 
       
   134 					
       
   135 	@return		Pointer to buffer containing the entire encoded field.
       
   136 	 			Responsibility for deallocating the memory is also passed.
       
   137 	@pre 		The function StartHeaderL should have been called.
       
   138 	@post		Encoder is reset ready to be used again.
       
   139 	@leave		HBufC8::NewL leaves, if the new 8 bit heap descriptor cannot be created.
       
   140 
       
   141 */
       
   142 EXPORT_C HBufC8* CWspHeaderEncoder::EndHeaderL()
       
   143 	{
       
   144 	__ASSERT_DEBUG(iArray.Count()==1,User::Panic(KWspCodecPanicCategory, EWspCodecPanicEndValueLengthNotCalled));
       
   145 	// concatenate array elements and return.
       
   146 
       
   147 	HBufC8* outputBuffer = HBufC8::NewL(iTotalLength);
       
   148 
       
   149 	CDesC8Array* desc = iArray[0];
       
   150 	TInt count = desc->Count();
       
   151 	for (TInt jj=0; jj<count; ++jj) 
       
   152 		{
       
   153 		(outputBuffer->Des()).Append((*desc)[jj]);
       
   154 		}
       
   155 
       
   156 	desc->Reset();
       
   157 	iTotalLength=0;
       
   158 	return outputBuffer;
       
   159 	}
       
   160 
       
   161 /**
       
   162   Encodes input Integer value and adds it to the encoded field. Choice of encoded 
       
   163   form dependent on the size of the input.Either ShortInt or LongInt method chosen.
       
   164 					
       
   165   @param 		aInt	Integer value to be encoded.
       
   166   @pre			StartHeaderL needs to have been called.
       
   167   @leave		KErrNoMemory
       
   168 */
       
   169 EXPORT_C void CWspHeaderEncoder::AddIntegerL(const TUint aInt)
       
   170 	{
       
   171 	// Determine if its a short or longInt we want
       
   172 	(aInt < KTopBitMask) ? AddShortIntL((TUint8) aInt) : AddLongIntL(aInt);
       
   173 	}
       
   174 
       
   175 /**
       
   176   Encodes input and adds it to the encoded field. Encodes parameter value using WSP 
       
   177   ShortInt method.
       
   178  					
       
   179   @param 			aValue	value to be encoded.
       
   180   @pre				StartHeaderL needs to have been called.
       
   181   @leave			KErrNoMemory
       
   182 */
       
   183 EXPORT_C void CWspHeaderEncoder::AddShortIntL(const TUint8 aValue)
       
   184 	{
       
   185 	const TInt arrayCount=iArray.Count();
       
   186 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   187 	CDesC8Array* desc=iArray[arrayCount-1];
       
   188 
       
   189 
       
   190 	// ShortInt shoud be a character 127 or less. With highest bit set to 1.
       
   191 	TUint8 shortInt = TWspPrimitiveEncoder::ShortInt(aValue);
       
   192 
       
   193 	desc->AppendL(TPtrC8(&shortInt, 1));
       
   194 	++iTotalLength;
       
   195 	}
       
   196 
       
   197 
       
   198 /**
       
   199   Encodes input and adds it to the encoded field. For short length the value must
       
   200   be between octet 0 - 31.
       
   201  	
       
   202   @param 		aValue	value to be encoded.
       
   203   @pre			StartHeaderL needs to have been called.
       
   204   @leave		KErrNoMemory, KErrOverflow if the value is greater than 31
       
   205 */
       
   206 EXPORT_C void CWspHeaderEncoder::AddShortLengthL(const TUint8 aValue)
       
   207 	{
       
   208 	const TInt arrayCount=iArray.Count();
       
   209 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   210 	CDesC8Array* desc=iArray[arrayCount-1];
       
   211 
       
   212 	// Check if the value is in the correct range ie octet 0-31
       
   213 	if(aValue > KUintVarIndicator)
       
   214 		User::Leave(KErrOverflow);
       
   215 
       
   216 	desc->AppendL(TPtrC8(&aValue, 1));
       
   217 	++iTotalLength;
       
   218 	}
       
   219 
       
   220 /**
       
   221   Encodes input and adds it to the encoded field. Encodes parameter value using WSP 
       
   222   LongInt method.
       
   223  					
       
   224   @param 			aValue	value to be encoded.
       
   225   @pre				StartHeaderL needs to have been called.
       
   226   @leave			KErrNoMemory
       
   227 */
       
   228 EXPORT_C void CWspHeaderEncoder::AddLongIntL(const TUint32 aValue)
       
   229 	{
       
   230 	const TInt arrayCount=iArray.Count();
       
   231 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   232 	CDesC8Array* desc=iArray[arrayCount-1];
       
   233 
       
   234 	HBufC8* buf = TWspPrimitiveEncoder::LongIntL(aValue);
       
   235 	CleanupStack::PushL(buf);
       
   236 
       
   237 	desc->AppendL(*buf);
       
   238 	iTotalLength+=buf->Length();
       
   239 
       
   240 	CleanupStack::PopAndDestroy(buf);
       
   241 	}
       
   242 	
       
   243 /**
       
   244   Encodes input and adds it to the encoded field. Encodes parameter value using WSP 
       
   245   UIntVar method.
       
   246  					
       
   247   @param 		aInt	value to be encoded.
       
   248   @pre			StartHeaderL needs to have been called.
       
   249   @leave		KErrNoMemory
       
   250 */
       
   251 EXPORT_C void CWspHeaderEncoder::AddUintVarL(const TUint aInt)
       
   252 	{
       
   253 	const TInt arrayCount=iArray.Count();
       
   254 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   255 	CDesC8Array* desc=iArray[arrayCount-1];
       
   256 
       
   257 	HBufC8*	buf = TWspPrimitiveEncoder::UintVarL(aInt);
       
   258 	CleanupStack::PushL(buf);
       
   259 
       
   260 	desc->AppendL(*buf);
       
   261 	iTotalLength+=buf->Length();
       
   262 
       
   263 	CleanupStack::PopAndDestroy(buf);
       
   264 	}
       
   265 
       
   266 /**
       
   267   Encodes input and adds it to the encoded field. Encodes parameter value using WSP
       
   268   TextString method.
       
   269  				   
       
   270   @param 			aText		value to be encoded.
       
   271   @pre				StartHeaderL needs to have been called.
       
   272   @leave			KErrNoMemory
       
   273 */
       
   274 EXPORT_C void CWspHeaderEncoder::AddTextStringL(const TDesC8& aText)
       
   275 	{	
       
   276 	const TInt arrayCount=iArray.Count();
       
   277 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   278 	CDesC8Array* desc=iArray[arrayCount-1];
       
   279 
       
   280 	HBufC8*	buf = TWspPrimitiveEncoder::TextStringL(aText);
       
   281 	CleanupStack::PushL(buf);
       
   282 	desc->AppendL(*buf);
       
   283 	iTotalLength+=buf->Length();
       
   284 	CleanupStack::PopAndDestroy(buf);
       
   285 	}
       
   286 
       
   287 /**
       
   288   Encodes input and adds it to the encoded field. Encodes parameter value using WSP
       
   289   TextString method.
       
   290   	   	
       
   291   @param 			aText		value to be encoded.
       
   292   @pre				StartHeaderL needs to have been called.
       
   293   @leave			KErrNoMemory
       
   294 */
       
   295 EXPORT_C void CWspHeaderEncoder::AddTextStringL(const RString& /* aText */)
       
   296 	{
       
   297 	User::Leave(KErrNotSupported);
       
   298 	}
       
   299 	
       
   300 /**
       
   301   Encodes input and adds it to the encoded field.Encodes parameter value using WSP 
       
   302   Date method.
       
   303  				   
       
   304   @param 			aDate		value to be encoded.
       
   305   @pre				StartHeaderL needs to have been called.
       
   306   @leave			KErrNoMemory
       
   307 */
       
   308 EXPORT_C void CWspHeaderEncoder::AddDateL(const TDateTime aDate)
       
   309 	{
       
   310 	const TInt arrayCount=iArray.Count();
       
   311 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   312 	CDesC8Array* desc=iArray[arrayCount-1];
       
   313 
       
   314 	HBufC8* buf = TWspPrimitiveEncoder::DateL(aDate);
       
   315 	CleanupStack::PushL(buf);
       
   316 	desc->AppendL(*buf);
       
   317 	iTotalLength+=buf->Length();
       
   318 	CleanupStack::PopAndDestroy(buf);
       
   319 	}
       
   320 	
       
   321 /**
       
   322   Encodes input and adds it to the encoded field. Adds value as-is to the encoded field.
       
   323  				   
       
   324   @param 	aToken	parameter added without encodeing. Should be a valid WSP token, 
       
   325   a 8 bit number > 0x7F (i.e. top bit set).
       
   326   @pre 		StartHeaderL and StartValueLengthL should have been called.
       
   327   @post		EndValueLengthL needs to be called subsequently.
       
   328 */
       
   329 EXPORT_C void CWspHeaderEncoder::AddTokenL(const TUint8 aToken)
       
   330 	{
       
   331 	const TInt arrayCount=iArray.Count();
       
   332 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   333 	CDesC8Array* desc=iArray[arrayCount-1];
       
   334 
       
   335 	TUint8 shortInt = (TUint8) (aToken); 
       
   336 	desc->AppendL(TPtrC8(&shortInt, 1));
       
   337 	++iTotalLength;
       
   338 	}
       
   339 	
       
   340 /**
       
   341   Encodes input and adds it to the encoded field. Encodes parameter value using WSP 
       
   342   TokenText method.
       
   343  				  
       
   344   @param 		aTokenText	value to be encoded.
       
   345   @leave		KErrNoMemory
       
   346 */
       
   347 EXPORT_C void CWspHeaderEncoder::AddTokenTextL(const TDesC8& aTokenText)
       
   348 	{
       
   349 	const TInt arrayCount=iArray.Count();
       
   350 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   351 
       
   352 	// Step through token text passed in and ensure there are no invalid characters
       
   353 	const TInt tokenTextLength = aTokenText.Length();
       
   354 	for( TInt ii = 0; ii<tokenTextLength; ++ii)
       
   355 		{
       
   356 		TUint8 currentChar = aTokenText[ii];
       
   357 		if( KTxtSeparators().Locate(currentChar) != KErrNotFound )
       
   358 			User::Leave(KErrCorrupt);
       
   359 		}
       
   360 	// Token text does not contain any invalid characters
       
   361 	HBufC8* buf = TWspPrimitiveEncoder::TextStringL(aTokenText);
       
   362 	CleanupStack::PushL(buf);
       
   363 	CDesC8Array* desc=iArray[arrayCount-1];
       
   364 	desc->AppendL(*buf);
       
   365 	iTotalLength += buf->Length();
       
   366 	CleanupStack::PopAndDestroy(buf);
       
   367 	}
       
   368 
       
   369 /**
       
   370   Encodes input and adds it to the encoded field. Adds value as-is to the encoded field.
       
   371  					
       
   372   @param 			aData		value to be encoded.
       
   373   @leave			KErrNoMemory
       
   374 */
       
   375 EXPORT_C void CWspHeaderEncoder::AddDataL(const TDesC8& aData)
       
   376 	{
       
   377 	const TInt arrayCount=iArray.Count();
       
   378 	__ASSERT_DEBUG(arrayCount>0,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartHeaderLNotCalled));
       
   379 	CDesC8Array* desc=iArray[arrayCount-1];
       
   380 	desc->AppendL(aData);
       
   381 	iTotalLength += aData.Length();
       
   382 	}
       
   383 
       
   384 /**
       
   385   From calling this function, the length in bytes of all encodings added subsequently will
       
   386   be calculated and stored as part of the encoded string, as specified in WSP spec.Can be nested. i.e.
       
   387   @code
       
   388 	 encoder->StartHeaderL();
       
   389 	 encoder->StartValueLengthL();
       
   390 	 encoder->StartValueLengthL();
       
   391 	 encoder->AddLongIntL();
       
   392 	 encoder->EndValueLengthL();
       
   393 	 encoder->AddTextStringL();
       
   394 	 encoder->EndValueLengthL();
       
   395 	 HBufC8* output = encoder->EndHeaderL();
       
   396   @endcode
       
   397  	
       
   398   @pre 			StartHeaderL should have been called.
       
   399   @post			EndValueLengthL needs to be called subsequently.
       
   400   @leave		KErrNoMemory
       
   401 */
       
   402 EXPORT_C void CWspHeaderEncoder::StartValueLengthL()
       
   403 	{
       
   404 	// Create new buffer;
       
   405 	CDesC8Array* buffer = new (ELeave) CDesC8ArrayFlat(KDesArrayGranularity);
       
   406 	CleanupStack::PushL(buffer);
       
   407 	User::LeaveIfError(iArray.Append(buffer));
       
   408 	CleanupStack::Pop(buffer);
       
   409 	}
       
   410 
       
   411 /**
       
   412   Needs to be called at the point in the construction of a header when ValueLength 
       
   413   can be calculated.
       
   414  					  
       
   415   @pre 			StartHeaderL and StartValueLengthL should have been called.
       
   416   @post			ValueLength has been calculated and added, together with the
       
   417  				encoded header, to the internal representation of the header buffer.
       
   418   @leave		KErrNoMemory
       
   419 */
       
   420 EXPORT_C void CWspHeaderEncoder::EndValueLengthL()
       
   421 	{
       
   422 	const TInt arrayCount=iArray.Count();
       
   423 	__ASSERT_ALWAYS(arrayCount>1,User::Panic(KWspCodecPanicCategory, EWspCodecPanicStartValueLengthNotCalled));
       
   424 
       
   425 	// Calculate the length of the current buffer.
       
   426 	// and append it onto the previous buffer. [length value, then data]
       
   427 	TUint32 valueLength=0;
       
   428 
       
   429 
       
   430 	CDesC8Array* desc=iArray[arrayCount-1]; // current descriptor being dealt with
       
   431 	CDesC8Array* parentDesc=iArray[arrayCount-2]; // parent descriptor to which it must be added.
       
   432 
       
   433 	TInt buffersToAdd=desc->Count();
       
   434 	TInt ii=buffersToAdd;
       
   435 
       
   436 	// Check the length of all parameters (not the first element in tha array, the field name)
       
   437 	while (ii)
       
   438 		valueLength+=(*desc)[--ii].Length();
       
   439 	
       
   440 	// Remove desc from array. Will have to delete also.
       
   441 	iArray.Remove(arrayCount-1);
       
   442 	CleanupStack::PushL(desc);
       
   443 
       
   444 	// Depending of size of the length save as number or UintVar
       
   445 	if (valueLength < KUintVarIndicator)
       
   446 		{
       
   447 		// Value length represented by an 8 bit number.
       
   448 		AddShortLengthL( (TUint8) valueLength);
       
   449 		}
       
   450 	else
       
   451 		{
       
   452 		// Value length represented by an 8bit value indicating a UIntVar follows,
       
   453 		// followed by a UIntVar
       
   454 		AddShortLengthL( (TUint8) KUintVarIndicator);
       
   455 		AddUintVarL(valueLength);
       
   456 		}
       
   457 
       
   458 	// Add field value, parameters etc.
       
   459 	ii=0;
       
   460 	while (ii<buffersToAdd)
       
   461 		parentDesc->AppendL((*desc)[ii++]);
       
   462 
       
   463 	CleanupStack::PopAndDestroy(desc);
       
   464 	}
       
   465 
       
   466 
       
   467 
       
   468 
       
   469 //**********************************************************************************
       
   470 
       
   471 /**
       
   472   Takes a TUint8 parameter, and sets the top bit. As specified for the WSP ShortInt 
       
   473   encoding method.
       
   474  					
       
   475   @param 		aValue number to be encoded.
       
   476   @return 		Output, encoded as a TUint8, representation of the header buffer.
       
   477  				If input greater that 127 (invalid input), returns 0
       
   478 */
       
   479 EXPORT_C TUint8 TWspPrimitiveEncoder::ShortInt(const TUint8 aValue)
       
   480 	{
       
   481 	// ShortInt should be a character 127 or less. With highest bit set to 1.
       
   482 	return (aValue > KWSPQuoteCharacter) ? (TUint8) 0: (TUint8) (aValue | KTopBitMask); 
       
   483 	}
       
   484 
       
   485 /**
       
   486   Takes a TUint32 parameter and encodes it using the WSP specified LongInt method.
       
   487   	
       
   488   @param 			aValue number to be encoded.
       
   489   @return 			Output, encoded HBufC8 buffer. 
       
   490   @leave			KErrNoMemory
       
   491 */
       
   492 EXPORT_C HBufC8* TWspPrimitiveEncoder::LongIntL(const TUint32 aValue)
       
   493 	{
       
   494 	// Consists of size and up to number of 30 bytes.
       
   495 	// for a TInt32 the maximum is 4 bytes long.
       
   496 	// Check size of number, to determine number of bytes needed to store it.
       
   497 
       
   498 	TUint8 size = 0; // maximum value is 4 with a 32bit integer
       
   499 	TUint32 value=aValue;
       
   500 	do {
       
   501 		++size;
       
   502 		value >>=KLongIntOctetShift; ; // shift by 8 bits.
       
   503 		} while (value>0);
       
   504 
       
   505 	HBufC8* output = HBufC8::NewL(size+1);
       
   506 	TPtr8 outPtr(output->Des());
       
   507 
       
   508 	outPtr.Append(size);
       
   509 	TInt ii = size;
       
   510 	while (ii-- >0) 
       
   511 		{		
       
   512 		outPtr.Append( (TUint8) (aValue>>ii*KLongIntOctetShift) );
       
   513 		}
       
   514 
       
   515 	return output;
       
   516 	}
       
   517 
       
   518 /**
       
   519   Takes a TUint32 parameter and encodes it using the WSP specified UintVar method.
       
   520   					
       
   521   @param 			aInt number to be encoded.
       
   522   @return 			Output, encoded HBufC8 buffer. 
       
   523   @leave			KErrNoMemory
       
   524 */
       
   525 EXPORT_C HBufC8* TWspPrimitiveEncoder::UintVarL(const TUint32 aInt)
       
   526 	{
       
   527 	TUint8 size = 0; // maximum value is 5 with a 32bit integer
       
   528 	TUint32 value=aInt;
       
   529 	do {
       
   530 		++size;
       
   531 		value >>=KUIntVarOctetShift; ; // shift by 7 bits.
       
   532 		} while (value>0);
       
   533 
       
   534 	HBufC8* output = HBufC8::NewL(size);
       
   535 	TPtr8 outPtr(output->Des());
       
   536 
       
   537 	TInt ii = size; 
       
   538 	while (--ii > 0)
       
   539 		{
       
   540 		outPtr.Append( (TUint8)(aInt>>(KUIntVarOctetShift*(ii))  & KWSPQuoteCharacter) | KCarryBitMask); 
       
   541 		} 
       
   542 
       
   543 	// Finally the first 7 bits, last octet, do not set first bit.
       
   544 	outPtr.Append( (TUint8)(aInt & KWSPQuoteCharacter) ); // Add even if 0 value.
       
   545 
       
   546 	return output;
       
   547 	}
       
   548 
       
   549 /**
       
   550   Takes a RString parameter and encodes it using the WSP specified TextString method.
       
   551   					
       
   552   @param 			aText string to be encoded.
       
   553   @return 			Output, encoded HBufC8 buffer. 
       
   554   @leave			KErrNoMemory
       
   555 */
       
   556 EXPORT_C HBufC8* TWspPrimitiveEncoder::TextStringL(const RString  /* aText*/ )
       
   557 	{
       
   558 	User::Leave(KErrNotSupported);
       
   559 	return NULL;
       
   560 	}
       
   561 
       
   562 /**
       
   563   Takes a TDesC8 parameter and encodes it using the WSP specified TextString method.
       
   564   					
       
   565   @param 			aText string to be encoded.
       
   566   @return 			Output, encoded HBufC8 buffer. 
       
   567   @leave			KErrNoMemory
       
   568 */
       
   569 EXPORT_C HBufC8* TWspPrimitiveEncoder::TextStringL(const TDesC8& aText)
       
   570 	{
       
   571 	HBufC8* output=NULL;
       
   572 	TInt stringLength = aText.Length();
       
   573 	TUint8 firstChar = 0;
       
   574 	TUint8 lastChar = 0;
       
   575 	if(stringLength>0)
       
   576 		{
       
   577 		firstChar = aText[0];
       
   578 		lastChar = aText[stringLength-1];
       
   579 		}
       
   580 
       
   581 	TPtr8 outPtr(NULL,0);
       
   582 	if (firstChar > KWSPQuoteCharacter)
       
   583 		{
       
   584 		// Apply WSP rule: first character of the string not 7bit add QuoteCharacter.
       
   585 		// Add the quote character and include space for the NULL character
       
   586 		stringLength+=2;
       
   587 		output =  HBufC8::NewL(stringLength); 
       
   588 		outPtr.Set(output->Des());
       
   589 
       
   590 		outPtr.Append(KWSPQuoteCharacter);
       
   591 		outPtr.Append(aText);
       
   592 		}
       
   593 	else if (firstChar==KWSPQuote && lastChar==KWSPQuote)
       
   594 		{
       
   595 		// Apply WSP rule: if quoted string, remove the closing quote
       
   596 		output =  HBufC8::NewL(stringLength); 
       
   597 		outPtr.Set(output->Des());
       
   598 		outPtr.Append(aText);
       
   599 		outPtr.SetLength(stringLength-1);
       
   600 		}
       
   601 	else
       
   602 		{
       
   603 		stringLength+=1; // terminating NULL char
       
   604 		output =  HBufC8::NewL(stringLength); 
       
   605 		outPtr.Set(output->Des());
       
   606 		outPtr.Append(aText);
       
   607 		}
       
   608 
       
   609 	// Terminate string with 0x00
       
   610 	outPtr.Append(KWspStringTerminator);
       
   611 	return output;
       
   612 	}
       
   613 
       
   614 /**
       
   615   Takes a TDateTime parameter and encodes it using the WSP specified Date encoding method.
       
   616   
       
   617   @param 			aDate value to be encoded.
       
   618   @return 			Output, encoded HBufC8 buffer. 
       
   619   @leave			KErrNoMemory
       
   620 */
       
   621 EXPORT_C HBufC8* TWspPrimitiveEncoder::DateL(const TDateTime aDate)
       
   622 	{
       
   623 	TTime baseTime(TDateTime(1970,EJanuary,0,0,0,0,0));
       
   624 	TTime dateTime(aDate);
       
   625 	TTimeIntervalSeconds interval;
       
   626 	dateTime.SecondsFrom(baseTime, interval);
       
   627 
       
   628 	return LongIntL(interval.Int());
       
   629 	}
       
   630