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