applayerpluginsandutils/httpprotocolplugins/wspheadercodec/CWspHeaderWriter.cpp
changeset 0 b16258d2340f
equal deleted inserted replaced
-1:000000000000 0:b16258d2340f
       
     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 // System Includes
       
    17 #include <wspstringconstants.h>
       
    18 #include <wspparamconstants.h>
       
    19 #include <wspcontenttypes.h>
       
    20 #include <wspregcontenttypes.h>
       
    21 #include <wspcharactersets.h>
       
    22 #include <wspstdconstants.h>
       
    23 #include <wsplanguages.h>
       
    24 #include <wsptypeconstants.h>
       
    25 
       
    26 // User Includes
       
    27 #include "cheaderfield.h"
       
    28 #include "cwspheaderwriter.h"
       
    29 
       
    30 const TInt KOffset = 1;				// Offset as the WspLanguages string table does not have 0x80 in it
       
    31 const TInt KShortIntLimit = 128;	// A short integer can be within the range of 0-127
       
    32 
       
    33 CWspHeaderWriter* CWspHeaderWriter::NewL(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
       
    34 	{
       
    35 	return new(ELeave)CWspHeaderWriter(aStrPool, aStrTable, aCodec);
       
    36 	}
       
    37 
       
    38 CWspHeaderWriter* CWspHeaderWriter::NewLC(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
       
    39 	{
       
    40 	CWspHeaderWriter* self = CWspHeaderWriter::NewL(aStrPool, aStrTable, aCodec);
       
    41 	CleanupStack::PushL(self);
       
    42 	return self;
       
    43 	}
       
    44 
       
    45 CWspHeaderWriter::CWspHeaderWriter(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
       
    46 	: iStrPool(aStrPool), iStrTable(aStrTable), iCodec(aCodec)
       
    47 	{
       
    48 	}
       
    49 
       
    50 CWspHeaderWriter::~CWspHeaderWriter()
       
    51 	{
       
    52 	}
       
    53 
       
    54 void CWspHeaderWriter::EncodeHeaderL(RHeaderField& aHeader)
       
    55 	{
       
    56 	switch(aHeader.Name().Index(iStrTable))
       
    57 		{
       
    58 		case WSP::EAccept:
       
    59 			{
       
    60 			EncodeAcceptL(aHeader);
       
    61 			} break;
       
    62 		case WSP::EAcceptCharsetDep:
       
    63 		case WSP::EAcceptCharset:
       
    64 			{
       
    65 			EncodeAcceptCharsetL(aHeader);
       
    66 			} break;
       
    67 		case WSP::EAcceptEncodingDep:
       
    68 		case WSP::EAcceptEncoding:
       
    69 			{
       
    70 			EncodeAcceptEncodingL(aHeader);
       
    71 			} break;
       
    72 		case WSP::EAcceptLanguage:
       
    73 			{
       
    74 			EncodeAcceptLanguageL(aHeader);
       
    75 			} break;
       
    76 		case WSP::EAllow:
       
    77 			{
       
    78 			EncodeAllowL(aHeader);
       
    79 			} break;
       
    80 		case WSP::EAuthorization:
       
    81 			{
       
    82 			EncodeAuthorizationL(aHeader);
       
    83 			} break;
       
    84 		case WSP::EContentEncoding:
       
    85 			{
       
    86 			EncodeContentEncodingL(aHeader);
       
    87 			} break;
       
    88 		case WSP::EContentLanguage:
       
    89 			{
       
    90 			EncodeContentLanguageL(aHeader);
       
    91 			} break;
       
    92 		case WSP::EContentLocation:
       
    93 		case WSP::EFrom:
       
    94 		case WSP::EProfile:
       
    95 		case WSP::EReferer:
       
    96 		case WSP::EUpgrade:
       
    97 		case WSP::EUserAgent:
       
    98 		case WSP::EVia:
       
    99 			{
       
   100 			GenericEncodeTextStringL(aHeader);
       
   101 			} break;
       
   102 		case WSP::EContentMD5:
       
   103 			{
       
   104 			EncodeContentMD5L(aHeader);
       
   105 			} break;
       
   106 		case WSP::EContentRangeDep:
       
   107 		case WSP::EContentRange:
       
   108 			{
       
   109 			EncodeContentRangeL(aHeader);
       
   110 			} break;
       
   111 		case WSP::EContentType:
       
   112 			{
       
   113 			EncodeContentTypeL(aHeader);
       
   114 			} break;
       
   115 		case WSP::ECookie:
       
   116 			{
       
   117 			EncodeCookieL(aHeader);
       
   118 			} break;
       
   119 		case WSP::EDate:
       
   120 		case WSP::ELastModified:
       
   121 			{
       
   122 			GenericEncodeDateL(aHeader);
       
   123 			} break;
       
   124 		case WSP::EEncodingVersion:
       
   125 			{
       
   126 			EncodeEncodingVersionL(aHeader);
       
   127 			} break;
       
   128 		case WSP::EExpect:
       
   129 			{
       
   130 			EncodeExpectL(aHeader);
       
   131 			} break;
       
   132 		case WSP::EPragma:
       
   133 			{
       
   134 			EncodePragmaL(aHeader);
       
   135 			} break;
       
   136 		case WSP::EProfileDiff:
       
   137 			{
       
   138 			EncodeProfileDiffL(aHeader);
       
   139 			} break;
       
   140 		case WSP::ERange:
       
   141 			{
       
   142 			EncodeRangeL(aHeader);
       
   143 			} break;
       
   144 		case WSP::ETE:
       
   145 			{
       
   146 			EncodeTEL(aHeader);
       
   147 			} break;
       
   148 		case WSP::ETrailer:
       
   149 			{
       
   150 			EncodeTrailerL(aHeader);
       
   151 			} break;
       
   152 		case WSP::EWarning:
       
   153 			{
       
   154 			EncodeWarningL(aHeader);
       
   155 			} break;
       
   156 		case WSP::EXWapApplicationId:
       
   157 			{
       
   158 			EncodeXWapApplicationIdL(aHeader);
       
   159 			} break;
       
   160 		default:
       
   161 			User::Leave(KErrNotSupported);
       
   162 			break;
       
   163 		}
       
   164 	}
       
   165 
       
   166 
       
   167 void CWspHeaderWriter::EncodeAcceptL(RHeaderField& aHeader) const
       
   168 	{
       
   169 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   170 	partIter.First();
       
   171 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   172 	CleanupStack::PushL(encoder);
       
   173 	TInt token = EncodeFieldName(aHeader.Name());
       
   174 	TInt partCount = 0;
       
   175 	TBool requireValueLength = EFalse;
       
   176 	aHeader.BeginRawDataL();
       
   177 	while (!partIter.AtEnd())
       
   178 		{
       
   179 		if (token == KErrNotFound)
       
   180 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   181 		else
       
   182 			encoder->StartHeaderL((TUint8)token);
       
   183 		const CHeaderFieldPart* part = partIter();
       
   184 		if (part != NULL)
       
   185 			{
       
   186 			++partCount;
       
   187 			TInt numParam = part->NumParameters();
       
   188 			if (numParam > 0)
       
   189 				{
       
   190 				requireValueLength = ETrue;
       
   191 				encoder->StartValueLengthL();
       
   192 				}
       
   193 			THTTPHdrVal value = part->Value();
       
   194 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   195 				{
       
   196 				TInt typeValue = EncodeContentTypeValue(value);
       
   197 				if (typeValue < KShortIntLimit && typeValue > KErrNotFound)
       
   198 					encoder->AddShortIntL((TUint8)typeValue);
       
   199 				else if (typeValue == KErrNotFound)
       
   200 					{
       
   201 					TInt registeredValue = value.StrF().Index(WSPRegContentTypes::Table);
       
   202 					if (registeredValue > KErrNotFound)
       
   203 						{
       
   204 						if (!requireValueLength)
       
   205 							{
       
   206 							encoder->StartValueLengthL();
       
   207 							requireValueLength = ETrue;
       
   208 							}
       
   209 						const TInt KContentTypeOffset = 0x0201;	// Offset for the Registered Content Type value string table
       
   210 						encoder->AddLongIntL(registeredValue + KContentTypeOffset);
       
   211 						}
       
   212 					else if (registeredValue == KErrNotFound)
       
   213 						{
       
   214 						User::LeaveIfError(CheckTextString(value.StrF()));
       
   215 						encoder->AddTextStringL(value.StrF().DesC());
       
   216 						}
       
   217 					}
       
   218 
       
   219 				THeaderFieldParamIter paramIter = part->Parameters();
       
   220 				paramIter.First();
       
   221 				while (!paramIter.AtEnd())
       
   222 					{
       
   223 					const CHeaderFieldParam* param = paramIter();
       
   224 					if (param != NULL)
       
   225 						EncodeParameterL(*param, *encoder);
       
   226 					++paramIter;
       
   227 					}
       
   228 				if (requireValueLength)
       
   229 					encoder->EndValueLengthL();
       
   230 				}
       
   231 			else
       
   232 				User::Leave(KErrCorrupt);
       
   233 			}
       
   234 
       
   235 		HBufC8* buffer = encoder->EndHeaderL();
       
   236 		CleanupStack::PushL(buffer);
       
   237 		TInt startPos = 0;
       
   238 		// If there is more than one header part it is necessary to append the name of the
       
   239 		// header to the buffer
       
   240 		if (partCount == 1)
       
   241 			startPos = EncodeHeaderNameL(aHeader);
       
   242 		TPtrC8 data(buffer->Mid(startPos));
       
   243 		aHeader.WriteRawDataL(data);
       
   244 		CleanupStack::PopAndDestroy(buffer);
       
   245 		++partIter;
       
   246 		}
       
   247 	aHeader.CommitRawData();
       
   248 	CleanupStack::PopAndDestroy(encoder);
       
   249 	}
       
   250 
       
   251 void CWspHeaderWriter::EncodeAcceptCharsetL(RHeaderField& aHeader) const
       
   252 	{
       
   253 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   254 	partIter.First();
       
   255 	aHeader.BeginRawDataL();
       
   256 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   257 	CleanupStack::PushL(encoder);
       
   258 	TInt token = EncodeFieldName(aHeader.Name());
       
   259 	TInt partCount = 0;
       
   260 	while (!partIter.AtEnd())
       
   261 		{
       
   262 		if (token == KErrNotFound)
       
   263 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   264 		else
       
   265 			encoder->StartHeaderL((TUint8)token);
       
   266 		TBool requireValueLength = EFalse;
       
   267 		const CHeaderFieldPart* part = partIter();
       
   268 		if (part != NULL)
       
   269 			{
       
   270 			++partCount;
       
   271 			TInt numParam = part->NumParameters();
       
   272 			if (numParam > 0)
       
   273 				{
       
   274 				requireValueLength = ETrue;
       
   275 				encoder->StartValueLengthL();
       
   276 				}
       
   277 			THTTPHdrVal value = part->Value();
       
   278 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   279 				{
       
   280 				// Check for '*' (Any-charset) and that the WSP version is greater than 1.2
       
   281 				if ((value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::EAny) 
       
   282 					&& (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_2))
       
   283 					{
       
   284 					encoder->AddTokenL(128);		// '*' is encoded as <Octet 128>
       
   285 					}
       
   286 				else
       
   287 					{
       
   288 					TInt charValue = GetCharacterSetValue(value.StrF());
       
   289 					switch(charValue)
       
   290 						{
       
   291 						case KErrNotFound:
       
   292 							{
       
   293 							User::LeaveIfError(CheckTextString(value.StrF()));
       
   294 							encoder->AddTextStringL(value.StrF().DesC());
       
   295 							} break;
       
   296 						default:
       
   297 							{
       
   298 							if (charValue < KShortIntLimit)
       
   299 								encoder->AddShortIntL((TUint8)charValue);
       
   300 							else
       
   301 								{
       
   302 								if (!requireValueLength)
       
   303 									{
       
   304 									encoder->StartValueLengthL();
       
   305 									requireValueLength = ETrue;
       
   306 									}
       
   307 								encoder->AddLongIntL(charValue);
       
   308 								}
       
   309 							} break;
       
   310 						}
       
   311 					}
       
   312 
       
   313 				// Check if we have any parameters
       
   314 				THeaderFieldParamIter paramIter = part->Parameters();
       
   315 				paramIter.First();
       
   316 				while (!paramIter.AtEnd())
       
   317 					{
       
   318 					const CHeaderFieldParam* param = paramIter();
       
   319 					THTTPHdrVal paramValue = param->Value();
       
   320 					HBufC8* qValue = EncodeQValueL(paramValue.StrF());
       
   321 					CleanupStack::PushL(qValue);
       
   322 					if (qValue != NULL)
       
   323 						encoder->AddDataL(*qValue);
       
   324 					++paramIter;
       
   325 					CleanupStack::PopAndDestroy(qValue);
       
   326 					}
       
   327 				}
       
   328 			else
       
   329 				User::Leave(KErrCorrupt);
       
   330 			}
       
   331 
       
   332 		// If we have a Q-value then we need to calculate the value-length
       
   333 		if (requireValueLength)
       
   334 			encoder->EndValueLengthL();
       
   335 		
       
   336 		HBufC8* buffer = encoder->EndHeaderL();
       
   337 		CleanupStack::PushL(buffer);
       
   338 		TInt startPos = 0;		
       
   339 		// If there is more than one header part it is necessary to append the name of the
       
   340 		// header to the buffer
       
   341 		if (partCount == 1)
       
   342 			startPos = EncodeHeaderNameL(aHeader);
       
   343 		TPtrC8 data(buffer->Mid(startPos));
       
   344 		aHeader.WriteRawDataL(data);
       
   345 		CleanupStack::PopAndDestroy(buffer);
       
   346 		++partIter;
       
   347 		}
       
   348 	aHeader.CommitRawData();
       
   349 	CleanupStack::PopAndDestroy(encoder);
       
   350 	}
       
   351 
       
   352 void CWspHeaderWriter::EncodeAcceptEncodingL(RHeaderField& aHeader) const
       
   353 	{
       
   354 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   355 	partIter.First();
       
   356 	TInt partCount = 0;
       
   357 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   358 	CleanupStack::PushL(encoder);
       
   359 	TInt token = EncodeFieldName(aHeader.Name());	
       
   360 	aHeader.BeginRawDataL();
       
   361 	while (!partIter.AtEnd())
       
   362 		{
       
   363 		if (token == KErrNotFound)
       
   364 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   365 		else
       
   366 			encoder->StartHeaderL((TUint8)token);
       
   367 		TBool requireValueLength = EFalse;
       
   368 		const CHeaderFieldPart* part = partIter();
       
   369 		if (part != NULL)
       
   370 			{
       
   371 			++partCount;
       
   372 			TInt numParam = part->NumParameters();
       
   373 			if (numParam > 0)
       
   374 				{
       
   375 				requireValueLength = ETrue;
       
   376 				encoder->StartValueLengthL();
       
   377 				}
       
   378 			THTTPHdrVal value = part->Value();
       
   379 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   380 				{
       
   381 				TInt encValue = value.StrF().Index(WSPStdConstants::Table);
       
   382 				// Check for '*' (Any-encoding) and that the WSP version is greater than 1.2
       
   383 				if ((encValue == WSPStdConstants::EAny) 
       
   384 					&& (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_2))
       
   385 					{
       
   386 					if (!requireValueLength)
       
   387 						{
       
   388 						encoder->StartValueLengthL();
       
   389 						requireValueLength = ETrue;
       
   390 						}
       
   391 					encoder->AddTokenL(131);				// '*' is encoded as <Octet 131>
       
   392 					}
       
   393 				else
       
   394 					{
       
   395 					switch(encValue)
       
   396 						{
       
   397 						case WSPStdConstants::EGzip:		// Gzip is encoded as <Octet 128>
       
   398 							{
       
   399 							encoder->AddTokenL(128);
       
   400 							} break;
       
   401 						case WSPStdConstants::ECompress:	// Compress is encoded as <Octet 129>
       
   402 							{
       
   403 							encoder->AddTokenL(129);
       
   404 							} break;
       
   405 						case WSPStdConstants::EDeflate:		// Deflate is encoded as <Octet 130>
       
   406 							{
       
   407 							encoder->AddTokenL(130);
       
   408 							} break;
       
   409 						default:
       
   410 							{
       
   411 							encoder->AddTokenTextL(value.StrF().DesC());
       
   412 							} break;
       
   413 						}
       
   414 					}
       
   415 			
       
   416 				THeaderFieldParamIter paramIter = part->Parameters();
       
   417 				paramIter.First();
       
   418 				while (!paramIter.AtEnd())
       
   419 					{
       
   420 					const CHeaderFieldParam* param = paramIter();
       
   421 					THTTPHdrVal paramValue = param->Value();
       
   422 					HBufC8* qValue = EncodeQValueL(paramValue.StrF());
       
   423 					CleanupStack::PushL(qValue);
       
   424 					if (qValue != NULL)
       
   425 						encoder->AddDataL(*qValue);
       
   426 					CleanupStack::PopAndDestroy(qValue);
       
   427 					++paramIter;
       
   428 					}
       
   429 				}
       
   430 			else
       
   431 				User::Leave(KErrCorrupt);
       
   432 			}
       
   433 
       
   434 		if (requireValueLength)
       
   435 			encoder->EndValueLengthL();
       
   436 		
       
   437 		HBufC8* buffer = encoder->EndHeaderL();
       
   438 		CleanupStack::PushL(buffer);
       
   439 		TInt startPos = 0;	
       
   440 		// If there is more than one header part it is necessary to append the name of the
       
   441 		// header to the buffer
       
   442 		if (partCount == 1)
       
   443 			startPos = EncodeHeaderNameL(aHeader);
       
   444 		TPtrC8 data(buffer->Mid(startPos));
       
   445 		aHeader.WriteRawDataL(data);
       
   446 		CleanupStack::PopAndDestroy(buffer);
       
   447 		++partIter;
       
   448 		}
       
   449 	aHeader.CommitRawData();
       
   450 	CleanupStack::PopAndDestroy(encoder);
       
   451 	}
       
   452 
       
   453 void CWspHeaderWriter::EncodeAcceptLanguageL(RHeaderField& aHeader) const
       
   454 	{
       
   455 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   456 	partIter.First();
       
   457 	TInt partCount = 0;
       
   458 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   459 	CleanupStack::PushL(encoder);
       
   460 	TInt token = EncodeFieldName(aHeader.Name());
       
   461 	aHeader.BeginRawDataL();
       
   462 	while (!partIter.AtEnd())
       
   463 		{
       
   464 		if (token == KErrNotFound)
       
   465 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   466 		else
       
   467 			encoder->StartHeaderL((TUint8)token);
       
   468 		TBool requireValueLength = EFalse;
       
   469 		const CHeaderFieldPart* part = partIter();
       
   470 		if (part != NULL)
       
   471 			{
       
   472 			++partCount;
       
   473 			TInt numParam = part->NumParameters();
       
   474 			if (numParam > 0)
       
   475 				{
       
   476 				requireValueLength = ETrue;
       
   477 				encoder->StartValueLengthL();
       
   478 				}
       
   479 			THTTPHdrVal value = part->Value();
       
   480 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   481 				{
       
   482 				TInt langValue = value.StrF().Index(WSPLanguages::Table);
       
   483 				switch(langValue)
       
   484 					{
       
   485 					case WSPLanguages::EAnyLanguage:
       
   486 						{
       
   487 						encoder->AddTokenL(128);		// '*' (Any-language) is encoded as <Octet 128>
       
   488 						} break;
       
   489 					case KErrNotFound:
       
   490 						{
       
   491 						User::LeaveIfError(CheckTextString(value.StrF()));
       
   492 						encoder->AddTextStringL(value.StrF().DesC());
       
   493 						} break;
       
   494 					default:
       
   495 						{
       
   496 						if (langValue < KShortIntLimit)
       
   497 							encoder->AddShortIntL((TUint8)langValue);
       
   498 						else
       
   499 							{
       
   500 							if (!requireValueLength)
       
   501 								{
       
   502 								encoder->StartValueLengthL();
       
   503 								requireValueLength = ETrue;
       
   504 								}
       
   505 							encoder->AddLongIntL(langValue + KOffset);
       
   506 							}
       
   507 						} break;
       
   508 					}
       
   509 
       
   510 				THeaderFieldParamIter paramIter = part->Parameters();
       
   511 				paramIter.First();
       
   512 				while (!paramIter.AtEnd())
       
   513 					{
       
   514 					const CHeaderFieldParam* param = paramIter();
       
   515 					THTTPHdrVal paramValue = param->Value();
       
   516 					HBufC8* qValue = EncodeQValueL(paramValue.StrF());
       
   517 					CleanupStack::PushL(qValue);
       
   518 					if (qValue != NULL)
       
   519 						encoder->AddDataL(*qValue);
       
   520 					++paramIter;
       
   521 					CleanupStack::PopAndDestroy(qValue);
       
   522 					}
       
   523 				}
       
   524 			else
       
   525 				User::Leave(KErrCorrupt);
       
   526 			}
       
   527 
       
   528 		if (requireValueLength)
       
   529 			encoder->EndValueLengthL();
       
   530 		
       
   531 		HBufC8* buffer = encoder->EndHeaderL();
       
   532 		CleanupStack::PushL(buffer);
       
   533 		TInt startPos = 0;	
       
   534 		// If there is more than one header part it is necessary to append the name of the
       
   535 		// header to the buffer
       
   536 		if (partCount == 1)
       
   537 			startPos = EncodeHeaderNameL(aHeader);
       
   538 		TPtrC8 data(buffer->Mid(startPos));
       
   539 		aHeader.WriteRawDataL(data);
       
   540 		CleanupStack::PopAndDestroy(buffer);
       
   541 		++partIter;
       
   542 		}
       
   543 	aHeader.CommitRawData();
       
   544 	CleanupStack::PopAndDestroy(encoder);
       
   545 	}
       
   546 
       
   547 void CWspHeaderWriter::EncodeAllowL(RHeaderField& aHeader) const
       
   548 	{
       
   549 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   550 	aHeader.BeginRawDataL();
       
   551 	TInt partCount = 0;
       
   552 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   553 	CleanupStack::PushL(encoder);
       
   554 	TInt token = EncodeFieldName(aHeader.Name());
       
   555 	partIter.First();
       
   556 	while (!partIter.AtEnd())
       
   557 		{
       
   558 		if (token == KErrNotFound)
       
   559 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   560 		else
       
   561 			encoder->StartHeaderL((TUint8)token);
       
   562 		const CHeaderFieldPart* part = partIter();
       
   563 		if (part != NULL)
       
   564 			{
       
   565 			++partCount;
       
   566 			THTTPHdrVal value = part->Value();
       
   567 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   568 				{
       
   569 				TUint8 allowNumber = 0;
       
   570 				TInt allowValue = value.StrF().Index(WSPTypeConstants::Table);
       
   571 				switch(allowValue)
       
   572 					{
       
   573 					case WSPTypeConstants::EGet:
       
   574 						{
       
   575 						allowNumber = 64;		// Get is encoded as 0x40
       
   576 						} break;
       
   577 					case WSPTypeConstants::EOptions:
       
   578 						{
       
   579 						allowNumber = 65;		// Options is encoded as 0x41
       
   580 						} break;
       
   581 					case WSPTypeConstants::EHead:
       
   582 						{
       
   583 						allowNumber = 66;		// Head is encoded as 0x42
       
   584 						} break;
       
   585 					case WSPTypeConstants::EDelete:
       
   586 						{
       
   587 						allowNumber = 67;		// Delete is encoded as 0x43
       
   588 						} break;
       
   589 					case WSPTypeConstants::ETrace:
       
   590 						{
       
   591 						allowNumber = 68;		// Trace is encoded as 0x44
       
   592 						} break;
       
   593 					case WSPTypeConstants::EPost:
       
   594 						{
       
   595 						allowNumber = 96;		// Post is encoded as 0x60
       
   596 						} break;
       
   597 					case WSPTypeConstants::EPut:
       
   598 						{
       
   599 						allowNumber = 97;		// Put is encoded as 0x61
       
   600 						} break;
       
   601 					default:
       
   602 						User::Leave(KErrNotFound);
       
   603 						break;
       
   604 					}
       
   605 				encoder->AddShortIntL(allowNumber);
       
   606 				}
       
   607 			else
       
   608 				User::Leave(KErrCorrupt);
       
   609 			}
       
   610 		HBufC8* buffer = encoder->EndHeaderL();
       
   611 		CleanupStack::PushL(buffer);
       
   612 		TInt startPos = 0;
       
   613 		if (partCount == 1)
       
   614 			startPos = EncodeHeaderNameL(aHeader);
       
   615 		TPtrC8 data(buffer->Mid(startPos));
       
   616 		aHeader.WriteRawDataL(data);
       
   617 		CleanupStack::PopAndDestroy(buffer);
       
   618 		++partIter;
       
   619 		}
       
   620 	aHeader.CommitRawData();
       
   621 	CleanupStack::PopAndDestroy(encoder);
       
   622 	}
       
   623 
       
   624 void CWspHeaderWriter::EncodeAuthorizationL(RHeaderField& aHeader) const
       
   625 	{
       
   626 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   627 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   628 	CleanupStack::PushL(encoder);
       
   629 	TInt token = EncodeFieldName(aHeader.Name());
       
   630 	partIter.First();
       
   631 	if (!partIter.AtEnd())
       
   632 		{
       
   633 		if (token == KErrNotFound)
       
   634 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   635 		else
       
   636 			encoder->StartHeaderL((TUint8)token);
       
   637 		const CHeaderFieldPart* part = partIter();
       
   638 		if (part != NULL)
       
   639 			{
       
   640 			THTTPHdrVal value = part->Value();
       
   641 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   642 				{
       
   643 				encoder->StartValueLengthL();
       
   644 				// Check to see if the first part is 'Basic'
       
   645 				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::EBasic)
       
   646 					{
       
   647 					// If it is, then encode Basic as <Octet 128> and then iterate through the
       
   648 					// following parts which should contain the 'User-ID' and 'Password'
       
   649 					encoder->AddTokenL(128);
       
   650 					++partIter;
       
   651 					while (!partIter.AtEnd())
       
   652 						{
       
   653 						value = partIter()->Value();
       
   654 						if(value.Type() == THTTPHdrVal::KStrFVal)
       
   655 							{
       
   656 							User::LeaveIfError(CheckTextString(value.StrF()));
       
   657 							encoder->AddTextStringL(value.StrF().DesC());
       
   658 							++partIter;
       
   659 							}
       
   660 						else
       
   661 							User::Leave(KErrCorrupt);
       
   662 						}
       
   663 					}
       
   664 				// Otherwise, the first part is an 'Authentication-scheme' with zero or more parameters
       
   665 				else
       
   666 					{
       
   667 					encoder->AddTokenTextL(value.StrF().DesC());
       
   668 					THeaderFieldParamIter paramIter = part->Parameters();
       
   669 					paramIter.First();
       
   670 					while (!paramIter.AtEnd())
       
   671 						{
       
   672 						const CHeaderFieldParam* param = paramIter();
       
   673 						if (param != NULL)
       
   674 							EncodeParameterL(*param, *encoder);
       
   675 						++paramIter;
       
   676 						}
       
   677 					}
       
   678 				encoder->EndValueLengthL();
       
   679 				}
       
   680 			else
       
   681 				User::Leave(KErrCorrupt);
       
   682 			}
       
   683 
       
   684 		aHeader.BeginRawDataL();	
       
   685 		HBufC8* buffer = encoder->EndHeaderL();
       
   686 		CleanupStack::PushL(buffer);
       
   687 		TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
   688 		aHeader.WriteRawDataL(data);
       
   689 		CleanupStack::PopAndDestroy(buffer);
       
   690 		aHeader.CommitRawData();
       
   691 		}
       
   692 	CleanupStack::PopAndDestroy(encoder);
       
   693 	}
       
   694 
       
   695 void CWspHeaderWriter::EncodeContentEncodingL(RHeaderField& aHeader) const
       
   696 	{
       
   697 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   698 	aHeader.BeginRawDataL();
       
   699 	TInt partCount = 0;
       
   700 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   701 	CleanupStack::PushL(encoder);
       
   702 	TInt token = EncodeFieldName(aHeader.Name());
       
   703 	partIter.First();
       
   704 	while (!partIter.AtEnd())
       
   705 		{
       
   706 		if (token == KErrNotFound)
       
   707 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   708 		else
       
   709 			encoder->StartHeaderL((TUint8)token);
       
   710 		const CHeaderFieldPart* part = partIter();
       
   711 		if (part != NULL)
       
   712 			{
       
   713 			++partCount;
       
   714 			THTTPHdrVal value = part->Value();
       
   715 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   716 				{
       
   717 				TInt encValue = value.StrF().Index(WSPStdConstants::Table);
       
   718 				switch(encValue)
       
   719 					{
       
   720 					case WSPStdConstants::EGzip:
       
   721 						{
       
   722 						encoder->AddTokenL(128);		// Gzip is encoded as <Octet 128>
       
   723 						} break;
       
   724 					case WSPStdConstants::ECompress:
       
   725 						{
       
   726 						encoder->AddTokenL(129);		// Compress is encoded as <Octet 129>
       
   727 						} break;
       
   728 					case WSPStdConstants::EDeflate:
       
   729 						{
       
   730 						encoder->AddTokenL(130);		// Deflate is encoded as <Octet 130>
       
   731 						} break;
       
   732 					default:
       
   733 						{
       
   734 						encoder->AddTokenTextL(value.StrF().DesC());
       
   735 						} break;
       
   736 					}
       
   737 				}
       
   738 			else
       
   739 				User::Leave(KErrCorrupt);
       
   740 			}
       
   741 
       
   742 		HBufC8* buffer = encoder->EndHeaderL();
       
   743 		CleanupStack::PushL(buffer);
       
   744 		TInt startPos = 0;
       
   745 		if (partCount == 1)
       
   746 			startPos = EncodeHeaderNameL(aHeader);
       
   747 		TPtrC8 data(buffer->Mid(startPos));
       
   748 		aHeader.WriteRawDataL(data);
       
   749 		CleanupStack::PopAndDestroy(buffer);
       
   750 		++partIter;
       
   751 		}
       
   752 	aHeader.CommitRawData();
       
   753 	CleanupStack::PopAndDestroy(encoder);
       
   754 	}
       
   755 
       
   756 void CWspHeaderWriter::EncodeContentLanguageL(RHeaderField& aHeader) const
       
   757 	{
       
   758 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   759 	partIter.First();
       
   760 	TInt partCount = 0;
       
   761 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   762 	CleanupStack::PushL(encoder);
       
   763 	TInt token = EncodeFieldName(aHeader.Name());
       
   764 	aHeader.BeginRawDataL();
       
   765 	while (!partIter.AtEnd())
       
   766 		{
       
   767 		if (token == KErrNotFound)
       
   768 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   769 		else
       
   770 			encoder->StartHeaderL((TUint8)token);
       
   771 		const CHeaderFieldPart* part = partIter();
       
   772 		if (part != NULL)
       
   773 			{
       
   774 			++partCount;
       
   775 			THTTPHdrVal value = part->Value();
       
   776 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   777 				{
       
   778 				TInt langValue = value.StrF().Index(WSPLanguages::Table);
       
   779 				switch(langValue)
       
   780 					{
       
   781 					case WSPLanguages::EAnyLanguage:
       
   782 						{
       
   783 						encoder->AddTokenL(128);		// '*' (Any-language) is encoded as <Octet 128>
       
   784 						} break;
       
   785 					case KErrNotFound:
       
   786 						{
       
   787 						encoder->AddTokenTextL(value.StrF().DesC());
       
   788 						} break;
       
   789 					default:
       
   790 						{
       
   791 						if (langValue < KShortIntLimit)
       
   792 							encoder->AddShortIntL((TUint8)langValue);
       
   793 						else
       
   794 							encoder->AddLongIntL(langValue + KOffset);
       
   795 						} break;
       
   796 					}
       
   797 				}
       
   798 			else
       
   799 				User::Leave(KErrCorrupt);
       
   800 			}
       
   801 
       
   802 		HBufC8* buffer = encoder->EndHeaderL();
       
   803 		CleanupStack::PushL(buffer);
       
   804 		TInt startPos = 0;
       
   805 		if (partCount == 1)
       
   806 			startPos = EncodeHeaderNameL(aHeader);
       
   807 		TPtrC8 data(buffer->Mid(startPos));
       
   808 		aHeader.WriteRawDataL(data);
       
   809 		CleanupStack::PopAndDestroy(buffer);
       
   810 		++partIter;
       
   811 		}
       
   812 	aHeader.CommitRawData();
       
   813 	CleanupStack::PopAndDestroy(encoder);
       
   814 	}
       
   815 
       
   816 void CWspHeaderWriter::EncodeContentMD5L(RHeaderField& aHeader) const
       
   817 	{
       
   818 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   819 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   820 	CleanupStack::PushL(encoder);
       
   821 	TBool requireValueLength = EFalse;
       
   822 	TInt token = EncodeFieldName(aHeader.Name());
       
   823 	partIter.First();
       
   824 	if (!partIter.AtEnd())
       
   825 		{
       
   826 		if (token == KErrNotFound)
       
   827 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   828 		else
       
   829 			encoder->StartHeaderL((TUint8)token);
       
   830 		const CHeaderFieldPart* part = partIter();
       
   831 		if (part != NULL)
       
   832 			{
       
   833 			THTTPHdrVal value = part->Value();
       
   834 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   835 				{
       
   836 				encoder->StartValueLengthL();
       
   837 				encoder->AddDataL(value.StrF().DesC());
       
   838 				requireValueLength = ETrue;
       
   839 				}
       
   840 			else
       
   841 				User::Leave(KErrCorrupt);
       
   842 
       
   843 			if (requireValueLength)
       
   844 				encoder->EndValueLengthL();
       
   845 
       
   846 			aHeader.BeginRawDataL();	
       
   847 			HBufC8* buffer = encoder->EndHeaderL();
       
   848 			CleanupStack::PushL(buffer);
       
   849 			TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
   850 			aHeader.WriteRawDataL(data);
       
   851 			CleanupStack::PopAndDestroy(buffer);
       
   852 			aHeader.CommitRawData();
       
   853 			}
       
   854 		}
       
   855 	CleanupStack::PopAndDestroy(encoder);
       
   856 	}
       
   857 
       
   858 void CWspHeaderWriter::EncodeContentRangeL(RHeaderField& aHeader) const
       
   859 	{
       
   860 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   861 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   862 	CleanupStack::PushL(encoder);
       
   863 	TInt token = EncodeFieldName(aHeader.Name());
       
   864 	partIter.First();
       
   865 	if (!partIter.AtEnd())
       
   866 		{
       
   867 		if (token == KErrNotFound)
       
   868 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   869 		else
       
   870 			encoder->StartHeaderL((TUint8)token);
       
   871 		const CHeaderFieldPart* part = partIter();
       
   872 		if (part != NULL)
       
   873 			{
       
   874 			THTTPHdrVal value = part->Value();
       
   875 			if (value.Type() == THTTPHdrVal::KTIntVal)
       
   876 				{
       
   877 				encoder->StartValueLengthL();
       
   878 				encoder->AddUintVarL(value);
       
   879 				++partIter;
       
   880 				if (!partIter.AtEnd())
       
   881 					{
       
   882 					value = partIter()->Value();
       
   883 					if (value.Type() == THTTPHdrVal::KStrFVal)
       
   884 						{
       
   885 						// Check for '*' (Any-encoding) and that the WSP version is greater than 1.2
       
   886 						if ((value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::EAny)
       
   887 							&& (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_2))
       
   888 							{
       
   889 							encoder->AddTokenL(128);	// '*' is encoded as <Octet 128>
       
   890 							}
       
   891 						}
       
   892 					if (value.Type() == THTTPHdrVal::KTIntVal)
       
   893 						encoder->AddUintVarL(value);
       
   894 					}
       
   895 				encoder->EndValueLengthL();
       
   896 				}
       
   897 			else
       
   898 				User::Leave(KErrCorrupt);
       
   899 
       
   900 			aHeader.BeginRawDataL();	
       
   901 			HBufC8* buffer = encoder->EndHeaderL();
       
   902 			CleanupStack::PushL(buffer);
       
   903 			TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
   904 			aHeader.WriteRawDataL(data);
       
   905 			CleanupStack::PopAndDestroy(buffer);
       
   906 			aHeader.CommitRawData();
       
   907 			}
       
   908 		}
       
   909 	CleanupStack::PopAndDestroy(encoder);
       
   910 	}
       
   911 
       
   912 void CWspHeaderWriter::EncodeContentTypeL(RHeaderField& aHeader) const
       
   913 	{
       
   914 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   915 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   916 	CleanupStack::PushL(encoder);
       
   917 	TInt token = EncodeFieldName(aHeader.Name());
       
   918 	partIter.First();
       
   919 	TBool requireValueLength = EFalse;
       
   920 	if (!partIter.AtEnd())
       
   921 		{
       
   922 		if (token == KErrNotFound)
       
   923 			encoder->StartHeaderL(aHeader.Name().DesC());
       
   924 		else
       
   925 			encoder->StartHeaderL((TUint8)token);
       
   926 		const CHeaderFieldPart* part = partIter();
       
   927 		if (part != NULL)
       
   928 			{
       
   929 			TInt numParam = part->NumParameters();
       
   930 			if (numParam > 0)
       
   931 				{
       
   932 				requireValueLength = ETrue;
       
   933 				encoder->StartValueLengthL();
       
   934 				}
       
   935 			THTTPHdrVal value = part->Value();
       
   936 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
   937 				{
       
   938 				TInt typeValue = EncodeContentTypeValue(value);
       
   939 				if (typeValue < KShortIntLimit && typeValue > KErrNotFound)
       
   940 					encoder->AddShortIntL((TUint8)typeValue);
       
   941 				else if (typeValue == KErrNotFound)
       
   942 					{
       
   943 					TInt registeredValue = value.StrF().Index(WSPRegContentTypes::Table);
       
   944 					if (registeredValue > KErrNotFound)
       
   945 						{
       
   946 						if (!requireValueLength)
       
   947 							{
       
   948 							encoder->StartValueLengthL();
       
   949 							requireValueLength = ETrue;
       
   950 							}
       
   951 						const TInt KContentTypeOffset = 0x0201;	// Offset for the Registered Content Type value string table
       
   952 						encoder->AddLongIntL(registeredValue + KContentTypeOffset);
       
   953 						}
       
   954 					else if (registeredValue == KErrNotFound)
       
   955 						{
       
   956 						User::LeaveIfError(CheckTextString(value.StrF()));
       
   957 						encoder->AddTextStringL(value.StrF().DesC());
       
   958 						}
       
   959 					}
       
   960 				// check for params and append to temporary buffer
       
   961 				THeaderFieldParamIter paramIter = part->Parameters();
       
   962 				paramIter.First();
       
   963 				while (!paramIter.AtEnd())
       
   964 					{
       
   965 					const CHeaderFieldParam* param = paramIter();
       
   966 					if (param != NULL)
       
   967 						EncodeParameterL(*param, *encoder);
       
   968 					++paramIter;
       
   969 					}
       
   970 
       
   971 				if (requireValueLength)
       
   972 					encoder->EndValueLengthL();
       
   973 
       
   974 				aHeader.BeginRawDataL();	
       
   975 				HBufC8* buffer = encoder->EndHeaderL();
       
   976 				CleanupStack::PushL(buffer);
       
   977 				TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
   978 				aHeader.WriteRawDataL(data);
       
   979 				CleanupStack::PopAndDestroy(buffer);
       
   980 				aHeader.CommitRawData();
       
   981 				}
       
   982 			else
       
   983 				User::Leave(KErrCorrupt);
       
   984 			}
       
   985 		}
       
   986 	CleanupStack::PopAndDestroy(encoder);
       
   987 	}
       
   988 
       
   989 void CWspHeaderWriter::EncodeCookieL(RHeaderField& aHeader) const
       
   990 	{
       
   991 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
   992 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
   993 	CleanupStack::PushL(encoder);
       
   994 	TInt token = EncodeFieldName(aHeader.Name());
       
   995 	partIter.First();
       
   996 	if (!partIter.AtEnd())
       
   997 		{
       
   998 		if (token == KErrNotFound)
       
   999 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1000 		else
       
  1001 			encoder->StartHeaderL((TUint8)token);
       
  1002 		const CHeaderFieldPart* part = partIter();
       
  1003 		if (part != NULL)
       
  1004 			{
       
  1005 			THTTPHdrVal value = part->Value();
       
  1006 			// Encode the first part which is the Cookie-version value
       
  1007 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1008 				{
       
  1009 				encoder->StartValueLengthL();
       
  1010 				TUint8 versionValue = EncodeVersionValueL(value.StrF());
       
  1011 				if (versionValue == 0)
       
  1012 					{
       
  1013 					User::LeaveIfError(CheckTextString(value.StrF()));
       
  1014 					encoder->AddTextStringL(value.StrF().DesC());
       
  1015 					}
       
  1016 				else
       
  1017 					encoder->AddShortIntL(versionValue);
       
  1018 
       
  1019 				// Then move to the next part and iterate through all the parts that follow, appending
       
  1020 				// the parameters if any exist
       
  1021 				++partIter;
       
  1022 				while (!partIter.AtEnd())
       
  1023 					{
       
  1024 					CWspHeaderEncoder* cookieEncoder = CWspHeaderEncoder::NewL();
       
  1025 					CleanupStack::PushL(cookieEncoder);
       
  1026 					value = partIter()->Value();	// The first part is the Cookie-Name
       
  1027 					if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1028 						{
       
  1029 						cookieEncoder->StartHeaderL((TUint8)token);
       
  1030 						cookieEncoder->StartValueLengthL();
       
  1031 						User::LeaveIfError(CheckTextString(value.StrF()));
       
  1032 						cookieEncoder->AddTextStringL(value.StrF().DesC());
       
  1033 						++partIter;
       
  1034 						part = partIter();
       
  1035 						value = partIter()->Value();	// The second part is the Cookie-Value
       
  1036 						if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1037 							{
       
  1038 							User::LeaveIfError(CheckTextString(value.StrF()));
       
  1039 							cookieEncoder->AddTextStringL(value.StrF().DesC());
       
  1040 							THeaderFieldParamIter paramIter = part->Parameters();	// Now check for any parameters
       
  1041 							paramIter.First();
       
  1042 							while (!paramIter.AtEnd())
       
  1043 								{
       
  1044 								const CHeaderFieldParam* param = paramIter();
       
  1045 								if (param != NULL)
       
  1046 									EncodeParameterL(*param, *cookieEncoder);
       
  1047 								++paramIter;
       
  1048 								}
       
  1049 							}
       
  1050 						else
       
  1051 							User::Leave(KErrCorrupt);
       
  1052 
       
  1053 						cookieEncoder->EndValueLengthL();
       
  1054 						HBufC8* cookieBuffer = cookieEncoder->EndHeaderL();
       
  1055 						CleanupStack::PushL(cookieBuffer);
       
  1056 						// Remove the header name from the buffer and then check if 
       
  1057 						// the first byte is equal to 31 i.e. a length quote, and if so remove it
       
  1058 						TInt offset = 1;
       
  1059 						if (cookieBuffer->Des()[1] == 31)
       
  1060 							++offset;
       
  1061 						HBufC8* data = cookieBuffer->Mid(offset).AllocL();
       
  1062 						CleanupStack::PushL(data);
       
  1063 						encoder->AddDataL(*data);
       
  1064 						CleanupStack::PopAndDestroy(2, cookieBuffer);		// data. cookieBuffer
       
  1065 						}
       
  1066 					++partIter;
       
  1067 					part = partIter();
       
  1068 					CleanupStack::PopAndDestroy(cookieEncoder);
       
  1069 					}
       
  1070 				encoder->EndValueLengthL();
       
  1071 				}
       
  1072 			else
       
  1073 				User::Leave(KErrCorrupt);
       
  1074 			}	
       
  1075 		HBufC8* buffer = encoder->EndHeaderL();
       
  1076 		CleanupStack::PushL(buffer);
       
  1077 		TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
  1078 		aHeader.BeginRawDataL();
       
  1079 		aHeader.WriteRawDataL(data);
       
  1080 		CleanupStack::PopAndDestroy(buffer);
       
  1081 		aHeader.CommitRawData();
       
  1082 		}
       
  1083 	CleanupStack::PopAndDestroy(encoder);
       
  1084 	}
       
  1085 
       
  1086 void CWspHeaderWriter::EncodeEncodingVersionL(RHeaderField& aHeader) const
       
  1087 	{
       
  1088 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1089 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1090 	CleanupStack::PushL(encoder);
       
  1091 	TInt token = EncodeFieldName(aHeader.Name());
       
  1092 	partIter.First();
       
  1093 	if (!partIter.AtEnd())
       
  1094 		{
       
  1095 		if (token == KErrNotFound)
       
  1096 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1097 		else
       
  1098 			encoder->StartHeaderL((TUint8)token);
       
  1099 		const CHeaderFieldPart* part = partIter();
       
  1100 		if (part != NULL)
       
  1101 			{
       
  1102 			THTTPHdrVal value = part->Value();
       
  1103 			if (value.Type() == THTTPHdrVal::KStrFVal)		// There is a version-value in the first part
       
  1104 				{
       
  1105 				TUint8 versionValue = EncodeVersionValueL(value.StrF());
       
  1106 				if (versionValue == 0)
       
  1107 					{
       
  1108 					User::LeaveIfError(CheckTextString(value.StrF()));
       
  1109 					encoder->AddTextStringL(value.StrF().DesC());
       
  1110 					}
       
  1111 				else
       
  1112 					encoder->AddShortIntL(versionValue);
       
  1113 				}
       
  1114 			else if (value.Type() == THTTPHdrVal::KTIntVal)	// The first part is NOT a version-value but an int
       
  1115 				{
       
  1116 				encoder->StartValueLengthL();
       
  1117 				if (value.Int() < KShortIntLimit)
       
  1118 					encoder->AddShortIntL((TUint8)value);
       
  1119 				else
       
  1120 					User::Leave(KErrCorrupt);
       
  1121 
       
  1122 				++partIter;
       
  1123 				if (!partIter.AtEnd())
       
  1124 					{
       
  1125 					value = partIter()->Value();
       
  1126 					if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1127 						{
       
  1128 						TUint8 versionValue = EncodeVersionValueL(value.StrF());
       
  1129 						if (versionValue == 0)
       
  1130 							{
       
  1131 							User::LeaveIfError(CheckTextString(value.StrF()));
       
  1132 							encoder->AddTextStringL(value.StrF().DesC());
       
  1133 							}
       
  1134 						else
       
  1135 							encoder->AddShortIntL(versionValue);
       
  1136 						}
       
  1137 					}
       
  1138 				encoder->EndValueLengthL();
       
  1139 				}
       
  1140 			else
       
  1141 				User::Leave(KErrCorrupt);
       
  1142 
       
  1143 			aHeader.BeginRawDataL();	
       
  1144 			HBufC8* buffer = encoder->EndHeaderL();
       
  1145 			CleanupStack::PushL(buffer);
       
  1146 			TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
  1147 			aHeader.WriteRawDataL(data);
       
  1148 			CleanupStack::PopAndDestroy(buffer);
       
  1149 			aHeader.CommitRawData();
       
  1150 			}
       
  1151 		}
       
  1152 	CleanupStack::PopAndDestroy(encoder);
       
  1153 	}
       
  1154 
       
  1155 void CWspHeaderWriter::EncodeExpectL(RHeaderField& aHeader) const
       
  1156 	{
       
  1157 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1158 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1159 	CleanupStack::PushL(encoder);
       
  1160 	TInt token = EncodeFieldName(aHeader.Name());
       
  1161 	partIter.First();
       
  1162 	if (!partIter.AtEnd())
       
  1163 		{
       
  1164 		if (token == KErrNotFound)
       
  1165 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1166 		else
       
  1167 			encoder->StartHeaderL((TUint8)token);
       
  1168 		const CHeaderFieldPart* part = partIter();
       
  1169 		if (part != NULL)
       
  1170 			{
       
  1171 			THTTPHdrVal value = part->Value();
       
  1172 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1173 				{
       
  1174 				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::E100Continue)
       
  1175 					encoder->AddTokenL(128);		// 100-continue is encoded as <Octet 128>
       
  1176 				else
       
  1177 					{
       
  1178 					encoder->StartValueLengthL();
       
  1179 					while (!partIter.AtEnd())
       
  1180 						{
       
  1181 						value = partIter()->Value();
       
  1182 						if(value.Type() == THTTPHdrVal::KStrFVal)
       
  1183 							{
       
  1184 							TPtrC8 valueDes(value.StrF().DesC());
       
  1185 							if (valueDes[0] == 0x22)	// Check if we have a quoted-string
       
  1186 								{
       
  1187 								User::LeaveIfError(CheckTextString(value.StrF()));
       
  1188 								encoder->AddTextStringL(value.StrF().DesC());
       
  1189 								}
       
  1190 							else
       
  1191 								encoder->AddTokenTextL(value.StrF().DesC());
       
  1192 
       
  1193 							THeaderFieldParamIter paramIter = part->Parameters();
       
  1194 							paramIter.First();
       
  1195 							while (!paramIter.AtEnd())
       
  1196 								{
       
  1197 								const CHeaderFieldParam* param = paramIter();
       
  1198 								if (param != NULL)
       
  1199 									EncodeParameterL(*param, *encoder);
       
  1200 								++paramIter;
       
  1201 								}
       
  1202 							++partIter;
       
  1203 							part = partIter();
       
  1204 							}
       
  1205 						else
       
  1206 							User::Leave(KErrCorrupt);
       
  1207 						}
       
  1208 					encoder->EndValueLengthL();
       
  1209 					}
       
  1210 				}
       
  1211 			else
       
  1212 				User::Leave(KErrCorrupt);
       
  1213 			}
       
  1214 
       
  1215 		aHeader.BeginRawDataL();	
       
  1216 		HBufC8* buffer = encoder->EndHeaderL();
       
  1217 		CleanupStack::PushL(buffer);
       
  1218 		TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
  1219 		aHeader.WriteRawDataL(data);
       
  1220 		CleanupStack::PopAndDestroy(buffer);
       
  1221 		aHeader.CommitRawData();
       
  1222 		}
       
  1223 	CleanupStack::PopAndDestroy(encoder);
       
  1224 	}
       
  1225 
       
  1226 void CWspHeaderWriter::EncodePragmaL(RHeaderField& aHeader) const
       
  1227 	{
       
  1228 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1229 	partIter.First();
       
  1230 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1231 	CleanupStack::PushL(encoder);
       
  1232 	TBool requireValueLength = EFalse;
       
  1233 	TInt token = EncodeFieldName(aHeader.Name());
       
  1234 	if (!partIter.AtEnd())
       
  1235 		{
       
  1236 		if (token == KErrNotFound)
       
  1237 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1238 		else
       
  1239 			encoder->StartHeaderL((TUint8)token);
       
  1240 		const CHeaderFieldPart* part = partIter();
       
  1241 		if (part != NULL)
       
  1242 			{
       
  1243 			THTTPHdrVal value = part->Value();
       
  1244 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1245 				{
       
  1246 				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::ENoCache)
       
  1247 					encoder->AddTokenL(128);		// 'No-cache' is encoded as <Octet 128>
       
  1248 				else
       
  1249 					{
       
  1250 					THeaderFieldParamIter paramIter = part->Parameters();
       
  1251 					paramIter.First();
       
  1252 					while (!paramIter.AtEnd())
       
  1253 						{
       
  1254 						const CHeaderFieldParam* param = paramIter();
       
  1255 						if (param != NULL)
       
  1256 							{
       
  1257 							encoder->StartValueLengthL();
       
  1258 							EncodeParameterL(*param, *encoder);
       
  1259 							requireValueLength = ETrue;
       
  1260 							}
       
  1261 						++paramIter;
       
  1262 						}
       
  1263 					}
       
  1264 				if (requireValueLength)
       
  1265 					encoder->EndValueLengthL();
       
  1266 
       
  1267 				aHeader.BeginRawDataL();	
       
  1268 				HBufC8* buffer = encoder->EndHeaderL();
       
  1269 				CleanupStack::PushL(buffer);
       
  1270 				TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
  1271 				aHeader.WriteRawDataL(data);
       
  1272 				CleanupStack::PopAndDestroy(buffer);
       
  1273 				aHeader.CommitRawData();
       
  1274 				}
       
  1275 			else
       
  1276 				User::Leave(KErrCorrupt);
       
  1277 			}
       
  1278 		}
       
  1279 	CleanupStack::PopAndDestroy(encoder);
       
  1280 	}
       
  1281 	
       
  1282 void CWspHeaderWriter::EncodeProfileDiffL(RHeaderField& aHeader) const
       
  1283 	{
       
  1284 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1285 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1286 	CleanupStack::PushL(encoder);
       
  1287 	TInt partCount = 0;
       
  1288 	aHeader.BeginRawDataL();
       
  1289 	TInt token = EncodeFieldName(aHeader.Name());
       
  1290 	partIter.First();
       
  1291 	while (!partIter.AtEnd())
       
  1292 		{
       
  1293 		if (token == KErrNotFound)
       
  1294 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1295 		else
       
  1296 			encoder->StartHeaderL((TUint8)token);
       
  1297 		const CHeaderFieldPart* part = partIter();
       
  1298 		if (part != NULL)
       
  1299 			{
       
  1300 			++partCount;
       
  1301 			THTTPHdrVal value = part->Value();
       
  1302 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1303 				{
       
  1304 				encoder->StartValueLengthL();
       
  1305 				encoder->AddDataL(value.StrF().DesC());
       
  1306 				encoder->EndValueLengthL();
       
  1307 				}
       
  1308 			else
       
  1309 				User::Leave(KErrCorrupt);
       
  1310 			}
       
  1311 			
       
  1312 		HBufC8* buffer = encoder->EndHeaderL();
       
  1313 		CleanupStack::PushL(buffer);
       
  1314 		TInt startPos = 0;
       
  1315 		if (partCount == 1)
       
  1316 			startPos = EncodeHeaderNameL(aHeader);
       
  1317 		TPtrC8 data(buffer->Mid(startPos));
       
  1318 		aHeader.WriteRawDataL(data);
       
  1319 		CleanupStack::PopAndDestroy(buffer);
       
  1320 		++partIter;
       
  1321 		}
       
  1322 	aHeader.CommitRawData();
       
  1323 	CleanupStack::PopAndDestroy(encoder);
       
  1324 	}
       
  1325 
       
  1326 void CWspHeaderWriter::EncodeRangeL(RHeaderField& aHeader) const
       
  1327 	{
       
  1328 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1329 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1330 	CleanupStack::PushL(encoder);
       
  1331 	TInt token = EncodeFieldName(aHeader.Name());
       
  1332 	TInt partCount = 0;
       
  1333 	aHeader.BeginRawDataL();
       
  1334 	partIter.First();
       
  1335 	while (!partIter.AtEnd())
       
  1336 		{
       
  1337 		if (token == KErrNotFound)
       
  1338 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1339 		else
       
  1340 			encoder->StartHeaderL((TUint8)token);
       
  1341 		const CHeaderFieldPart* part = partIter();
       
  1342 		if (part != NULL)
       
  1343 			{
       
  1344 			++partCount;
       
  1345 			THTTPHdrVal value = part->Value();
       
  1346 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1347 				{
       
  1348 				encoder->StartValueLengthL();
       
  1349 				TInt rangeValue = value.StrF().Index(WSPStdConstants::Table);
       
  1350 				switch (rangeValue)
       
  1351 					{
       
  1352 					case WSPStdConstants::EByteRange:
       
  1353 						{
       
  1354 						encoder->AddTokenL(128);	// 'Byte-range' is encoded as <Octet 128>
       
  1355 						} break;
       
  1356 					case WSPStdConstants::ESuffixByteRange:
       
  1357 						{
       
  1358 						encoder->AddTokenL(129);	// 'Suffix-byte-range' is encoded as <Octet 129>
       
  1359 						} break;
       
  1360 					default:
       
  1361 						User::Leave(KErrCorrupt);
       
  1362 					}
       
  1363 				// Iterate through the parts that follow
       
  1364 				++partIter;
       
  1365 				while (!partIter.AtEnd())
       
  1366 					{
       
  1367 					value = partIter()->Value();
       
  1368 					if(value.Type() == THTTPHdrVal::KTIntVal)
       
  1369 						{
       
  1370 						encoder->AddUintVarL(value);
       
  1371 						++partIter;
       
  1372 						}
       
  1373 					else if(value.Type() == THTTPHdrVal::KStrFVal)
       
  1374 						{
       
  1375 						// Found the next header
       
  1376 						break;
       
  1377 						}
       
  1378 					else
       
  1379 						User::Leave(KErrCorrupt);
       
  1380 					}
       
  1381 				encoder->EndValueLengthL();
       
  1382 				}
       
  1383 			else
       
  1384 				User::Leave(KErrCorrupt);			
       
  1385 			}
       
  1386 
       
  1387 		HBufC8* buffer = encoder->EndHeaderL();
       
  1388 		CleanupStack::PushL(buffer);
       
  1389 		TInt startPos = 0;
       
  1390 		if (partCount == 1)
       
  1391 			startPos = EncodeHeaderNameL(aHeader);
       
  1392 		TPtrC8 data(buffer->Mid(startPos));
       
  1393 		aHeader.WriteRawDataL(data);
       
  1394 		CleanupStack::PopAndDestroy(buffer);
       
  1395 		}
       
  1396 	aHeader.CommitRawData();
       
  1397 	CleanupStack::PopAndDestroy(encoder);
       
  1398 	}
       
  1399 
       
  1400 void CWspHeaderWriter::EncodeTEL(RHeaderField& aHeader) const
       
  1401 	{
       
  1402 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1403 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1404 	CleanupStack::PushL(encoder);
       
  1405 	TInt token = EncodeFieldName(aHeader.Name());
       
  1406 	partIter.First();
       
  1407 	TBool requireValueLength = EFalse;
       
  1408 	aHeader.BeginRawDataL();
       
  1409 	TInt partCount = 0;
       
  1410 	while (!partIter.AtEnd())
       
  1411 		{
       
  1412 		if (token == KErrNotFound)
       
  1413 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1414 		else
       
  1415 			encoder->StartHeaderL((TUint8)token);
       
  1416 		const CHeaderFieldPart* part = partIter();
       
  1417 		if (part != NULL)
       
  1418 			{
       
  1419 			++partCount;
       
  1420 			TInt numParam = part->NumParameters();
       
  1421 			if (numParam > 0)
       
  1422 				{
       
  1423 				encoder->StartValueLengthL();
       
  1424 				requireValueLength = ETrue;
       
  1425 				}
       
  1426 			THTTPHdrVal value = part->Value();
       
  1427 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1428 				{
       
  1429 				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::ETrailers)
       
  1430 					encoder->AddTokenL(129);		// 'Trailers' is encoded as <Octet 129>
       
  1431 				else
       
  1432 					{
       
  1433 					if (!requireValueLength)
       
  1434 						{
       
  1435 						encoder->StartValueLengthL();
       
  1436 						requireValueLength = ETrue;
       
  1437 						}
       
  1438 					TInt encValue = value.StrF().Index(WSPStdConstants::Table);
       
  1439 					switch(encValue)
       
  1440 						{
       
  1441 						case WSPStdConstants::EChunked:
       
  1442 							{
       
  1443 							encoder->AddTokenL(130);		// 'Chunked' is encoded as <Octet 130>
       
  1444 							} break;
       
  1445 						case WSPStdConstants::EIdentity:
       
  1446 							{
       
  1447 							encoder->AddTokenL(131);		// 'Identity' is encoded as <Octet 131>
       
  1448 							} break;
       
  1449 						case WSPStdConstants::EGzip:
       
  1450 							{
       
  1451 							encoder->AddTokenL(132);		// 'Gzip' is encoded as <Octet 132>
       
  1452 							} break;
       
  1453 						case WSPStdConstants::ECompress:
       
  1454 							{
       
  1455 							encoder->AddTokenL(133);		// 'Compress' is encoded as <Octet 133>
       
  1456 							} break;
       
  1457 						case WSPStdConstants::EDeflate:
       
  1458 							{
       
  1459 							encoder->AddTokenL(134);		// 'Deflate' is encoded as <Octet 134>
       
  1460 							} break;
       
  1461 						default:
       
  1462 							{
       
  1463 							encoder->AddTokenTextL(value.StrF().DesC());
       
  1464 							} break;
       
  1465 						}
       
  1466 
       
  1467 					THeaderFieldParamIter paramIter = part->Parameters();
       
  1468 					paramIter.First();
       
  1469 					// Encode any parameters that exist.
       
  1470 					// A parameter consists of a Q-token and a Q-value
       
  1471 					while (!paramIter.AtEnd())
       
  1472 						{
       
  1473 						const CHeaderFieldParam* param = paramIter();
       
  1474 						if (param != NULL)			
       
  1475 							EncodeParameterL(*param, *encoder);
       
  1476 						++paramIter;
       
  1477 						}
       
  1478 					if (requireValueLength)
       
  1479 						encoder->EndValueLengthL();
       
  1480 					}
       
  1481 				}
       
  1482 			else
       
  1483 				User::Leave(KErrCorrupt);
       
  1484 			}
       
  1485 
       
  1486 		HBufC8* buffer = encoder->EndHeaderL();
       
  1487 		CleanupStack::PushL(buffer);
       
  1488 		TInt startPos = 0;
       
  1489 		if (partCount == 1)
       
  1490 			startPos = EncodeHeaderNameL(aHeader);
       
  1491 		TPtrC8 data(buffer->Mid(startPos));
       
  1492 		aHeader.WriteRawDataL(data);
       
  1493 		CleanupStack::PopAndDestroy(buffer);
       
  1494 		++partIter;
       
  1495 		}
       
  1496 	aHeader.CommitRawData();
       
  1497 	CleanupStack::PopAndDestroy(encoder);
       
  1498 	}
       
  1499 
       
  1500 void CWspHeaderWriter::EncodeTrailerL(RHeaderField& aHeader) const
       
  1501 	{
       
  1502 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1503 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1504 	CleanupStack::PushL(encoder);
       
  1505 	TInt token = EncodeFieldName(aHeader.Name());
       
  1506 	TInt partCount = 0;
       
  1507 	aHeader.BeginRawDataL();
       
  1508 	partIter.First();
       
  1509 	while (!partIter.AtEnd())
       
  1510 		{
       
  1511 		if (token == KErrNotFound)
       
  1512 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1513 		else
       
  1514 			encoder->StartHeaderL((TUint8)token);
       
  1515 		const CHeaderFieldPart* part = partIter();
       
  1516 		if (part != NULL)
       
  1517 			{
       
  1518 			++partCount;
       
  1519 			THTTPHdrVal value = part->Value();
       
  1520 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1521 				{
       
  1522 				TInt headerNameVal = EncodeFieldName(value.StrF());
       
  1523 				if (headerNameVal < KShortIntLimit && headerNameVal > KErrNotFound)
       
  1524 					encoder->AddShortIntL((TUint8)headerNameVal);
       
  1525 				else if (headerNameVal > 127)
       
  1526 					encoder->AddLongIntL(headerNameVal);
       
  1527 				else
       
  1528 					encoder->AddTokenTextL(value.StrF().DesC());
       
  1529 				}
       
  1530 			else
       
  1531 				User::Leave(KErrCorrupt);
       
  1532 			}
       
  1533 
       
  1534 		HBufC8* buffer = encoder->EndHeaderL();
       
  1535 		CleanupStack::PushL(buffer);
       
  1536 		TInt startPos = 0;
       
  1537 		if (partCount == 1)
       
  1538 			startPos = EncodeHeaderNameL(aHeader);
       
  1539 		TPtrC8 data(buffer->Mid(startPos));
       
  1540 		aHeader.WriteRawDataL(data);
       
  1541 		CleanupStack::PopAndDestroy(buffer);
       
  1542 		++partIter;
       
  1543 		}
       
  1544 	aHeader.CommitRawData();
       
  1545 	CleanupStack::PopAndDestroy(encoder);
       
  1546 	}
       
  1547 
       
  1548 void CWspHeaderWriter::EncodeWarningL(RHeaderField& aHeader) const
       
  1549 	{
       
  1550 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1551 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1552 	CleanupStack::PushL(encoder);
       
  1553 	TInt token = EncodeFieldName(aHeader.Name());
       
  1554 	partIter.First();
       
  1555 	if (!partIter.AtEnd())
       
  1556 		{
       
  1557 		if (token == KErrNotFound)
       
  1558 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1559 		else
       
  1560 			encoder->StartHeaderL((TUint8)token);
       
  1561 		const CHeaderFieldPart* part = partIter();
       
  1562 		if (part != NULL)
       
  1563 			{
       
  1564 			THTTPHdrVal value = part->Value();
       
  1565 			if (value.Type() == THTTPHdrVal::KTIntVal)
       
  1566 				{
       
  1567 				TUint8 warningNumber = 0;
       
  1568 				switch(value)
       
  1569 					{
       
  1570 					case 110:
       
  1571 						{
       
  1572 						warningNumber = 10;		// Warning code 110 is encoded as <Octet 10>
       
  1573 						} break;
       
  1574 					case 111:
       
  1575 						{
       
  1576 						warningNumber = 11;		// Warning code 111 is encoded as <Octet 11>
       
  1577 						} break;
       
  1578 					case 112:
       
  1579 						{
       
  1580 						warningNumber = 12;		// Warning code 112 is encoded as <Octet 12>
       
  1581 						} break;
       
  1582 					case 113:
       
  1583 						{
       
  1584 						warningNumber = 13;		// Warning code 113 is encoded as <Octet 13>
       
  1585 						} break;
       
  1586 					case 199:
       
  1587 					case 299:
       
  1588 						{
       
  1589 						warningNumber = 99;		// Warning codes 199 and 299 are encoded as <Octet 99>
       
  1590 						} break;
       
  1591 					case 214:
       
  1592 						{
       
  1593 						warningNumber = 14;		// Warning code 214 is encoded as <Octet 14>
       
  1594 						} break;
       
  1595 					default:
       
  1596 						break;
       
  1597 					}
       
  1598 
       
  1599 				++partIter;
       
  1600 				if (partIter.AtEnd())	// Check to see if we have only one part
       
  1601 					encoder->AddShortIntL(warningNumber);
       
  1602 				else
       
  1603 					{
       
  1604 					encoder->StartValueLengthL();			// If there is more than one part then it is
       
  1605 					encoder->AddShortIntL(warningNumber);	// necessary to work out the value-length
       
  1606 					while (!partIter.AtEnd())
       
  1607 						{
       
  1608 						value = partIter()->Value();
       
  1609 						if(value.Type() == THTTPHdrVal::KStrFVal)
       
  1610 							{
       
  1611 							User::LeaveIfError(CheckTextString(value.StrF()));
       
  1612 							encoder->AddTextStringL(value.StrF().DesC());
       
  1613 							++partIter;
       
  1614 							}
       
  1615 						else
       
  1616 							User::Leave(KErrCorrupt);
       
  1617 						}
       
  1618 					encoder->EndValueLengthL();
       
  1619 					}
       
  1620 				}
       
  1621 			else
       
  1622 				User::Leave(KErrCorrupt);
       
  1623 			}
       
  1624 		aHeader.BeginRawDataL();	
       
  1625 		HBufC8* buffer = encoder->EndHeaderL();
       
  1626 		CleanupStack::PushL(buffer);
       
  1627 		TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
  1628 		aHeader.WriteRawDataL(data);
       
  1629 		CleanupStack::PopAndDestroy(buffer);
       
  1630 		aHeader.CommitRawData();
       
  1631 		}
       
  1632 	CleanupStack::PopAndDestroy(encoder);
       
  1633 	}
       
  1634 
       
  1635 void CWspHeaderWriter::EncodeXWapApplicationIdL(RHeaderField& aHeader) const
       
  1636 	{
       
  1637 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1638 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1639 	CleanupStack::PushL(encoder);
       
  1640 	TInt token = EncodeFieldName(aHeader.Name());
       
  1641 	partIter.First();
       
  1642 	if (!partIter.AtEnd())
       
  1643 		{
       
  1644 		if (token == KErrNotFound)
       
  1645 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1646 		else
       
  1647 			encoder->StartHeaderL((TUint8)token);
       
  1648 		const CHeaderFieldPart* part = partIter();
       
  1649 		if (part != NULL)
       
  1650 			{
       
  1651 			THTTPHdrVal value = part->Value();
       
  1652 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1653 				{
       
  1654 				User::LeaveIfError(CheckTextString(value.StrF()));
       
  1655 				encoder->AddTextStringL(value.StrF().DesC());
       
  1656 				}
       
  1657 			else if (value.Type() == THTTPHdrVal::KTIntVal)
       
  1658 				{
       
  1659 				if (value.Int() < KShortIntLimit)
       
  1660 					encoder->AddShortIntL((TUint8)(value.Int()));
       
  1661 				else
       
  1662 					encoder->AddLongIntL(value.Int());
       
  1663 				}
       
  1664 			else
       
  1665 				User::Leave(KErrCorrupt);
       
  1666 
       
  1667 			HBufC8* buffer = encoder->EndHeaderL();
       
  1668 			CleanupStack::PushL(buffer);
       
  1669 			TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
  1670 			aHeader.BeginRawDataL();
       
  1671 			aHeader.WriteRawDataL(data);
       
  1672 			CleanupStack::PopAndDestroy(buffer);
       
  1673 			aHeader.CommitRawData();
       
  1674 			}
       
  1675 		}
       
  1676 	CleanupStack::PopAndDestroy(encoder);
       
  1677 	}
       
  1678 
       
  1679 
       
  1680 //
       
  1681 // Generic methods
       
  1682 //
       
  1683 
       
  1684 void CWspHeaderWriter::GenericEncodeDateL(RHeaderField& aHeader) const
       
  1685 	{
       
  1686 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1687 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1688 	CleanupStack::PushL(encoder);
       
  1689 	TInt token = EncodeFieldName(aHeader.Name());
       
  1690 	partIter.First();
       
  1691 	if (!partIter.AtEnd())
       
  1692 		{
       
  1693 		if (token == KErrNotFound)
       
  1694 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1695 		else
       
  1696 			encoder->StartHeaderL((TUint8)token);
       
  1697 		const CHeaderFieldPart* part = partIter();
       
  1698 		if (part != NULL)
       
  1699 			{
       
  1700 			THTTPHdrVal value = part->Value();
       
  1701 			if (value.Type() == THTTPHdrVal::KDateVal)
       
  1702 				{
       
  1703 				encoder->AddDateL(value.DateTime());
       
  1704 				HBufC8* buffer = encoder->EndHeaderL();
       
  1705 				CleanupStack::PushL(buffer);
       
  1706 				TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
       
  1707 				aHeader.BeginRawDataL();
       
  1708 				aHeader.WriteRawDataL(data);
       
  1709 				CleanupStack::PopAndDestroy(buffer);
       
  1710 				aHeader.CommitRawData();
       
  1711 				}
       
  1712 			else
       
  1713 				User::Leave(KErrCorrupt);
       
  1714 			}
       
  1715 		}
       
  1716 	CleanupStack::PopAndDestroy(encoder);
       
  1717 	}
       
  1718 
       
  1719 void CWspHeaderWriter::GenericEncodeTextStringL(RHeaderField& aHeader) const
       
  1720 	{
       
  1721 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  1722 	aHeader.BeginRawDataL();
       
  1723 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  1724 	CleanupStack::PushL(encoder);
       
  1725 	TInt token = EncodeFieldName(aHeader.Name());
       
  1726 	TInt partCount = 0;
       
  1727 	partIter.First();
       
  1728 	while (!partIter.AtEnd())
       
  1729 		{
       
  1730 		if (token == KErrNotFound)
       
  1731 			encoder->StartHeaderL(aHeader.Name().DesC());
       
  1732 		else
       
  1733 			encoder->StartHeaderL((TUint8)token);
       
  1734 		const CHeaderFieldPart* part = partIter();
       
  1735 		if (part != NULL)
       
  1736 			{
       
  1737 			++partCount;
       
  1738 			THTTPHdrVal value = part->Value();
       
  1739 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  1740 				{
       
  1741 				User::LeaveIfError(CheckTextString(value.StrF()));
       
  1742 				encoder->AddTextStringL(value.StrF().DesC());
       
  1743 				}
       
  1744 			else
       
  1745 				User::Leave(KErrCorrupt);
       
  1746 			}
       
  1747 
       
  1748 		HBufC8* buffer = encoder->EndHeaderL();
       
  1749 		CleanupStack::PushL(buffer);
       
  1750 		TInt startPos = 0;
       
  1751 		if (partCount == 1)
       
  1752 			startPos = EncodeHeaderNameL(aHeader);
       
  1753 		TPtrC8 data(buffer->Mid(startPos));
       
  1754 		aHeader.WriteRawDataL(data);
       
  1755 		CleanupStack::PopAndDestroy(buffer);
       
  1756 		++partIter;
       
  1757 		}
       
  1758 	aHeader.CommitRawData();
       
  1759 	CleanupStack::PopAndDestroy(encoder);
       
  1760 	}
       
  1761 
       
  1762 void CWspHeaderWriter::EncodeParameterL(const CHeaderFieldParam& aHeaderFieldParam, CWspHeaderEncoder& aEncoder) const
       
  1763 	{
       
  1764 	THTTPHdrVal value = aHeaderFieldParam.Value();
       
  1765 	TInt paramIndex = EncodeParameterTokenValue(aHeaderFieldParam.Name());
       
  1766 	if (paramIndex == KErrNotFound)		// This is an untyped parameter
       
  1767 		{
       
  1768 		// Append the name as a string
       
  1769 		aEncoder.AddTokenTextL(aHeaderFieldParam.Name().DesC());
       
  1770 
       
  1771 		// Append the param value
       
  1772 		switch(value.Type())
       
  1773 			{
       
  1774 			case THTTPHdrVal::KTIntVal:
       
  1775 				{
       
  1776 				if (value.Int() < KShortIntLimit)
       
  1777 					aEncoder.AddShortIntL((TUint8)(value.Int()));
       
  1778 				else
       
  1779 					aEncoder.AddLongIntL(value.Int());
       
  1780 				} break;
       
  1781 			case THTTPHdrVal::KStrFVal:
       
  1782 				{
       
  1783 				User::LeaveIfError(CheckTextString(value.StrF()));
       
  1784 				aEncoder.AddTextStringL(value.StrF().DesC());
       
  1785 				} break;
       
  1786 			default:
       
  1787 				{
       
  1788 				User::Leave(KErrCorrupt);
       
  1789 				} break;
       
  1790 			}
       
  1791 		}
       
  1792 	else	// This is a typed parameter
       
  1793 		{
       
  1794 		// Check encoding version and adjust token as neccessary
       
  1795 		if (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_3)
       
  1796 			{
       
  1797 			switch (paramIndex)
       
  1798 				{
       
  1799 				case 0x05:
       
  1800 					paramIndex = 0x17;	// Name-token is encoded as 0x17 in WSP version 1.4
       
  1801 					break;
       
  1802 				case 0x06:
       
  1803 					paramIndex = 0x18;	// Filename-token is encoded as 0x18 in WSP version 1.4
       
  1804 					break;
       
  1805 				case 0x0A:
       
  1806 					paramIndex = 0x19;	// Start-token is encoded as 0x19 in WSP version 1.4
       
  1807 					break;
       
  1808 				case 0x0B:
       
  1809 					paramIndex = 0x1A;	// Start-info-token is encoded as 0x1A in WSP version 1.4
       
  1810 					break;
       
  1811 				case 0x0C:
       
  1812 					paramIndex = 0x1B;	// Comment-token is encoded as 0x1B in WSP version 1.4
       
  1813 					break;
       
  1814 				case 0x0D:
       
  1815 					paramIndex = 0x1C;	// Domain-token is encoded as 0x1C in WSP version 1.4
       
  1816 					break;
       
  1817 				case 0x0F:
       
  1818 					paramIndex = 0x1D;	// Path-token is encoded as 0x1D in WSP version 1.4
       
  1819 					break;
       
  1820 				default:
       
  1821 					break;
       
  1822 				}
       
  1823 			}
       
  1824 		// Append the name as an encoded value
       
  1825 		aEncoder.AddShortIntL((TUint8)paramIndex);
       
  1826 		
       
  1827 		// Append the param value
       
  1828 		switch(paramIndex)
       
  1829 			{
       
  1830 			case WSPParam::EQ:
       
  1831 				{
       
  1832 				HBufC8* qValue = EncodeQValueL(value.StrF());
       
  1833 				if (qValue != NULL)
       
  1834 					{
       
  1835 					CleanupStack::PushL(qValue);
       
  1836 					aEncoder.AddDataL(*qValue);
       
  1837 					CleanupStack::PopAndDestroy(qValue);
       
  1838 					}
       
  1839 				} break;
       
  1840 			case WSPParam::ECharset:
       
  1841 				{
       
  1842 				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::EAny)
       
  1843 					aEncoder.AddTokenL(128);	// '*' (Any-charset) is encoded as <Octet 128> 
       
  1844 				else
       
  1845 					{
       
  1846 					TInt charValue = GetCharacterSetValue(value.StrF());
       
  1847 					User::LeaveIfError(charValue);
       
  1848 					if (charValue < KShortIntLimit)
       
  1849 						aEncoder.AddShortIntL((TUint8)charValue);
       
  1850 					else
       
  1851 						aEncoder.AddLongIntL(charValue);
       
  1852 					}
       
  1853 				} break;
       
  1854 			case WSPParam::ELevel:
       
  1855 				{
       
  1856 				TUint8 versionValue = EncodeVersionValueL(value.StrF());
       
  1857 				if (versionValue == 0)
       
  1858 					{
       
  1859 					User::LeaveIfError(CheckTextString(value.StrF()));
       
  1860 					aEncoder.AddTextStringL(value.StrF().DesC());
       
  1861 					}
       
  1862 				else
       
  1863 					aEncoder.AddShortIntL(versionValue);
       
  1864 				} break;
       
  1865 			case WSPParam::EType:
       
  1866 			case WSPParam::EContentTypeType:
       
  1867 			case WSPParam::ESize:
       
  1868 			case WSPParam::EPadding:
       
  1869 			case WSPParam::ESEC:
       
  1870 			case WSPParam::EMaxAge:
       
  1871 				{
       
  1872 				if (value.Int() < KShortIntLimit)
       
  1873 					aEncoder.AddShortIntL((TUint8)value.Int());
       
  1874 				else
       
  1875 					aEncoder.AddLongIntL(value.Int());
       
  1876 				} break;
       
  1877 			case WSPParam::ENameDep:
       
  1878 			case WSPParam::EFilenameDep:
       
  1879 			case WSPParam::EStartDep:
       
  1880 			case WSPParam::EStartInfoDep:
       
  1881 			case WSPParam::ECommentDep:
       
  1882 			case WSPParam::EDomainDep:
       
  1883 			case WSPParam::EPathDep:
       
  1884 			case WSPParam::EName:
       
  1885 			case WSPParam::EFilename:
       
  1886 			case WSPParam::EStart:
       
  1887 			case WSPParam::EStartInfo:
       
  1888 			case WSPParam::EComment:
       
  1889 			case WSPParam::EDomain:
       
  1890 			case WSPParam::EPath:
       
  1891 			case WSPParam::EMAC:
       
  1892 				{
       
  1893 				TPtrC8 valueDes(value.StrF().DesC());
       
  1894 				if ((iCodec.GetWspVersion() < CWspHeaderCodec::EVersion1_4) || 
       
  1895 					(valueDes.Length() == 0) ||
       
  1896 					(valueDes[0] == 0x22))		// Check if we have a quoted-string
       
  1897 					{
       
  1898 					User::LeaveIfError(CheckTextString(value.StrF()));
       
  1899 					aEncoder.AddTextStringL(valueDes);
       
  1900 					}
       
  1901 				else
       
  1902 					{
       
  1903 					User::LeaveIfError(CheckTokenText(value.StrF()));
       
  1904 					aEncoder.AddTokenTextL(valueDes);
       
  1905 					}
       
  1906 				} break;
       
  1907 			case WSPParam::EDifferences:
       
  1908 				{
       
  1909 				TInt headerNameVal = EncodeFieldName(value.StrF());
       
  1910 				if (headerNameVal < KShortIntLimit && headerNameVal > KErrNotFound)
       
  1911 					aEncoder.AddShortIntL((TUint8)headerNameVal);
       
  1912 				else
       
  1913 					aEncoder.AddTokenTextL(value.StrF().DesC());
       
  1914 				} break;
       
  1915 			case WSPParam::ECreationDate:
       
  1916 			case WSPParam::EModificationDate:
       
  1917 			case WSPParam::EReadDate:
       
  1918 				{
       
  1919 				aEncoder.AddDateL(value.DateTime());
       
  1920 				} break;
       
  1921 			case WSPParam::ESecure:
       
  1922 				{
       
  1923 				aEncoder.AddTokenL(0);
       
  1924 				} break;
       
  1925 			default:
       
  1926 				{
       
  1927 				aEncoder.AddTokenTextL(value.StrF().DesC());
       
  1928 				} break;
       
  1929 			}
       
  1930 		}
       
  1931 	}
       
  1932 
       
  1933 TInt CWspHeaderWriter::GetCharacterSetValue(RStringF aCharSet) const
       
  1934 	{
       
  1935 	TInt value = KErrNotFound;
       
  1936 	switch(aCharSet.Index(WSPCharacterSets::Table))
       
  1937 		{
       
  1938 		case WSPCharacterSets::EBig5:
       
  1939 			{
       
  1940 			value =  0x07EA;		// Character set big5 is encoded as 0x07EA
       
  1941 			} break;
       
  1942 		case WSPCharacterSets::EIso10646ucs2:
       
  1943 			{
       
  1944 			value =  0x03E8;		// Character set iso-10646-ucs-2 is encoded as 0x03E8 
       
  1945 			} break;
       
  1946 		case WSPCharacterSets::EIso88591:
       
  1947 			{
       
  1948 			value =  0x04;		// Character set iso-8859-1 is encoded as 0x04
       
  1949 			} break;
       
  1950 		case WSPCharacterSets::EIso88592:
       
  1951 			{
       
  1952 			value =  0x05;		// Character set iso-8859-2 is encoded as 0x05
       
  1953 			} break;
       
  1954 		case WSPCharacterSets::EIso88593:
       
  1955 			{
       
  1956 			value =  0x06;		// Character set iso-8859-3 is encoded as 0x06
       
  1957 			} break;
       
  1958 		case WSPCharacterSets::EIso88594:
       
  1959 			{
       
  1960 			value =  0x07;		// Character set iso-8859-4 is encoded as 0x07
       
  1961 			} break;
       
  1962 		case WSPCharacterSets::EIso88595:
       
  1963 			{
       
  1964 			value =  0x08;		// Character set iso-8859-5 is encoded as 0x08
       
  1965 			} break;
       
  1966 		case WSPCharacterSets::EIso88596:
       
  1967 			{
       
  1968 			value =  0x09;		// Character set iso-8859-6 is encoded as 0x09
       
  1969 			} break;
       
  1970 		case WSPCharacterSets::EIso88597:
       
  1971 			{
       
  1972 			value =  0x0A;		// Character set iso-8859-9 is encoded as 0x0A
       
  1973 			} break;
       
  1974 		case WSPCharacterSets::EIso88598:
       
  1975 			{
       
  1976 			value =  0x0B;		// Character set iso-8859-8 is encoded as 0x0B
       
  1977 			} break;
       
  1978 		case WSPCharacterSets::EIso88599:
       
  1979 			{
       
  1980 			value =  0x0C;		// Character set iso-8859-9 is encoded as 0x0C
       
  1981 			} break;
       
  1982 		case WSPCharacterSets::EShiftJIS:
       
  1983 			{
       
  1984 			value =  0x11;		// Character set shift_JIS is encoded as 0x11
       
  1985 			} break;
       
  1986 		case WSPCharacterSets::EUsAscii:
       
  1987 			{
       
  1988 			value =  0x03;		// Character set us-ascii is encoded as 0x03
       
  1989 			} break;
       
  1990 		case WSPCharacterSets::EUtf8:
       
  1991 		case WSPCharacterSets::EGsmDefaultAlphabet:
       
  1992 			{
       
  1993 			value = 0x6A;		// Character sets utf-8 and gsm-default-alphabet are
       
  1994 			} break;			// encoded as 0x6A
       
  1995 		default:
       
  1996 			// Use default value of KErrNotFound
       
  1997 			break;
       
  1998 		}
       
  1999 	return value;
       
  2000 	}
       
  2001 
       
  2002 HBufC8* CWspHeaderWriter::EncodeQValueL(RStringF aQValue) const
       
  2003 	{
       
  2004 	TInt decPointPos = aQValue.DesC().Locate('.');
       
  2005 	if (decPointPos != KErrNotFound)
       
  2006 		{
       
  2007 		if ((decPointPos + 1) >= aQValue.DesC().Length())
       
  2008 			User::Leave(KErrCorrupt);
       
  2009 		TPtrC8 decValue(aQValue.DesC().Mid(decPointPos + 1));
       
  2010 		TLex8 intConvertDes(decValue);
       
  2011 		TInt convertedInt = 0;
       
  2012 		if (intConvertDes.Val(convertedInt) != KErrNone)
       
  2013 			User::Leave(KErrCorrupt);
       
  2014 		switch(decValue.Length())
       
  2015 			{
       
  2016 			case 1:
       
  2017 				convertedInt *= 10;
       
  2018 			case 2:
       
  2019 				++convertedInt;
       
  2020 				break;
       
  2021 			case 3:
       
  2022 				convertedInt += 100;
       
  2023 				break;
       
  2024 			default:
       
  2025 				User::Leave(KErrCorrupt);
       
  2026 				break;
       
  2027 			}
       
  2028 		return TWspPrimitiveEncoder::UintVarL(convertedInt);
       
  2029 		}
       
  2030 	return NULL;
       
  2031 	}
       
  2032 
       
  2033 TUint8 CWspHeaderWriter::EncodeVersionValueL(RStringF aVersionValue) const
       
  2034 	{
       
  2035 	TPtrC8 version(aVersionValue.DesC());
       
  2036 	TInt versionLength = version.Length();
       
  2037 	if (versionLength == 0)
       
  2038 		User::Leave(KErrCorrupt);
       
  2039 	TInt decimalPos = version.Locate('.');
       
  2040 	TUint8 majorVersion = 0;
       
  2041 	TUint8 minorVersion = 0x0F;
       
  2042 	if (decimalPos != KErrNotFound)
       
  2043 		{
       
  2044 		if ((decimalPos + 1) == versionLength)
       
  2045 			User::Leave(KErrCorrupt);
       
  2046 		TPtrC8 minorDes(version.Mid(decimalPos + 1));
       
  2047 		TLex8 convertMinor(minorDes);
       
  2048 		TInt convertedMinor = 0;
       
  2049 		if (convertMinor.Val(convertedMinor) != KErrNone)
       
  2050 			User::Leave(KErrCorrupt);
       
  2051 		if (convertedMinor > 14)	// The minor version number must be within the range 0-14
       
  2052 			return 0;
       
  2053 		else
       
  2054 			minorVersion = (TUint8)convertedMinor;
       
  2055 		}
       
  2056 	TPtrC8 majorDes;
       
  2057 	if (decimalPos == KErrNotFound)
       
  2058 		majorDes.Set(version);
       
  2059 	else
       
  2060 		majorDes.Set(version.Left(decimalPos));
       
  2061 
       
  2062 	TLex8 convertMajor(majorDes);
       
  2063 	TInt convertedInt = 0;
       
  2064 	if (convertMajor.Val(convertedInt) != KErrNone)
       
  2065 		User::Leave(KErrCorrupt);
       
  2066 	if (convertedInt > 7)			// The major version has a maximum value of 7
       
  2067 		return 0;
       
  2068 	else if (convertedInt > 0)		// and a minimum value of 1
       
  2069 		majorVersion = (TUint8)convertedInt;
       
  2070 	else
       
  2071 		User::Leave(KErrCorrupt);
       
  2072 		
       
  2073 	majorVersion <<= 4;								// Shift the bits across by four places so that
       
  2074 													// they are the most significant bits
       
  2075 	return (TUint8)(majorVersion | minorVersion);
       
  2076 	}
       
  2077 
       
  2078 TInt CWspHeaderWriter::EncodeFieldName(RStringF aFieldName) const
       
  2079 	{
       
  2080 	TInt fieldName = aFieldName.Index(iStrTable);
       
  2081 	const CWspHeaderCodec::TWspVersion wspVersion = iCodec.GetWspVersion();
       
  2082 
       
  2083 	// Check WSP version against encoded ranges
       
  2084 	switch(wspVersion)
       
  2085 		{
       
  2086 		case CWspHeaderCodec::EVersion1_1:
       
  2087 			{
       
  2088 			if(fieldName > 0x2E) // Highest header encoding is 0x2E in v1.1
       
  2089 				fieldName = KErrNotFound;
       
  2090 			} break;
       
  2091 		case CWspHeaderCodec::EVersion1_2:
       
  2092 			{
       
  2093 			if(fieldName > 0x37) // Highest header encoding is 0x2E in v1.2
       
  2094 				fieldName = KErrNotFound;
       
  2095 			} break;
       
  2096 		case CWspHeaderCodec::EVersion1_3:
       
  2097 			{
       
  2098 			if(fieldName > 0x43) // Highest header encoding is 0x2E in v1.3
       
  2099 				fieldName = KErrNotFound;
       
  2100 			} break;
       
  2101 		default: // version is 1.4 that can encode everything
       
  2102 			break;
       
  2103 		}
       
  2104 
       
  2105 	// Make any value changes based on WSP version
       
  2106 	TInt name = fieldName;
       
  2107 	switch(fieldName)
       
  2108 		{
       
  2109 		case WSP::EAcceptCharsetDep:
       
  2110 		case WSP::EAcceptCharset:
       
  2111 			{
       
  2112 			if (wspVersion < CWspHeaderCodec::EVersion1_3)
       
  2113 				name = 0x01;		// Version 1.1 of Accept-Charset is encoded as 0x01
       
  2114 			else
       
  2115 				name = 0x3B;		// The current version (1.3) of Accept-Charset is encoded as 0x3B
       
  2116 			} break;
       
  2117 		case WSP::EAcceptEncodingDep:
       
  2118 		case WSP::EAcceptEncoding:
       
  2119 			{
       
  2120 			if (wspVersion < CWspHeaderCodec::EVersion1_3)
       
  2121 				name = 0x02;		// Version 1.1 of Accept-Encoding is encoded as 0x02
       
  2122 			else
       
  2123 				name = 0x3C;		// The current version (1.3) of Accept-Encoding is encoded as 0x3C
       
  2124 			} break;
       
  2125 		case WSP::ECacheControlDep:
       
  2126 		case WSP::ECacheControlDep2:
       
  2127 		case WSP::ECacheControl:
       
  2128 			{
       
  2129 			if (wspVersion < CWspHeaderCodec::EVersion1_3)
       
  2130 				name = 0x08;		// Version 1.1 of Cache-Control is encoded as 0x08
       
  2131 			else if (wspVersion == CWspHeaderCodec::EVersion1_3)
       
  2132 				name = 0x3D;		// Version 1.3 of Cache-Control is encoded as 0x3D
       
  2133 			else
       
  2134 				name = 0x47;		// The current version (1.4) of Cache-Control is encoded as 0x47
       
  2135 			} break;
       
  2136 		case WSP::EContentRangeDep:
       
  2137 		case WSP::EContentRange:
       
  2138 			{
       
  2139 			if (wspVersion < CWspHeaderCodec::EVersion1_3)
       
  2140 				name = 0x10;		// Version 1.1 of Content-Range is encoded as 0x10
       
  2141 			else
       
  2142 				name = 0x3E;		// The current version (1.3) of Content-Range is encoded as 0x3E
       
  2143 			} break;
       
  2144 		case WSP::EContentDispositionDep:
       
  2145 		case WSP::EContentDisposition:
       
  2146 			{
       
  2147 			if (wspVersion < CWspHeaderCodec::EVersion1_4)
       
  2148 				name = 0x2E;		// Version 1.1 of Content-Disposition is encoded as 0x2E
       
  2149 			else
       
  2150 				name = 0x45;		// The current version (1.4) of Content-Disposition is encoded as 0x45
       
  2151 			} break;
       
  2152 		case WSP::EProfileWarningDep:
       
  2153 		case WSP::EProfileWarning:
       
  2154 			{
       
  2155 			if (wspVersion < CWspHeaderCodec::EVersion1_4)
       
  2156 				name = 0x37;		// Version 1.2 of Profile-Warning is encoded as 0x37
       
  2157 			else
       
  2158 				name = 0x44;		// The current version (1.4) of Profile-Warning is encoded as 0x44
       
  2159 			} break;
       
  2160 		default:
       
  2161 			// Use default return name of fieldName.
       
  2162 			break;
       
  2163 		}
       
  2164 	return name;
       
  2165 	}
       
  2166 
       
  2167 TInt CWspHeaderWriter::EncodeHeaderNameL(RHeaderField& aHeader) const
       
  2168 	{
       
  2169 	TInt headerLength = 0;
       
  2170 	TInt headerNameVal = EncodeFieldName(aHeader.Name());
       
  2171 	if (headerNameVal == KErrNotFound)
       
  2172 		{
       
  2173 		User::LeaveIfError(CheckTokenText(aHeader.Name()));
       
  2174 		headerLength = aHeader.Name().DesC().Length();
       
  2175 		}
       
  2176 	return ++headerLength;
       
  2177 	}
       
  2178 
       
  2179 TInt CWspHeaderWriter::CheckTokenText(RStringF aTokenText) const
       
  2180 	{
       
  2181 	const TUint8 KMinValidCharValue = 32;				// Minimum ASCII value for a valid character
       
  2182 	const TUint8 KMaxValidCharValue = 126;				// Maximum ASCII value for a valid character
       
  2183 	_LIT8(KTxtSeparators, "()<>@,;:\\\"/[]?={} ");		// Separator characters as defined in RFC2616
       
  2184 	
       
  2185 	// Go through each character in the string ensuring that it is within the acceptable ASCII range
       
  2186 	// and then check that the string does not contain any seperator characters.
       
  2187 	const TInt tokenTextLength = aTokenText.DesC().Length();
       
  2188 	for	(TInt ii = 0; ii < tokenTextLength; ++ii)
       
  2189 		{
       
  2190 		TUint8 currentChar = aTokenText.DesC()[ii];
       
  2191 		if ((currentChar < KMinValidCharValue) && (currentChar > KMaxValidCharValue))
       
  2192 			return KErrCorrupt;
       
  2193 		if (KTxtSeparators().Locate(currentChar) != KErrNotFound)
       
  2194 			return KErrCorrupt;
       
  2195 		}
       
  2196 	return KErrNone;
       
  2197 	}
       
  2198 
       
  2199 TInt CWspHeaderWriter::CheckTextString(RStringF aTextString) const
       
  2200 	{
       
  2201 	const TUint KHorizTab = 9;
       
  2202 	const TUint KLinefeed = 10;
       
  2203 	const TUint KCarriageReturn = 13;
       
  2204 	const TUint KSpace = 32;
       
  2205 	const TInt textStringLength = aTextString.DesC().Length();
       
  2206 	for	(TInt ii = 0; ii < textStringLength; ++ii)
       
  2207 		{
       
  2208 		TUint8 currentChar = aTextString.DesC()[ii];
       
  2209 		// Check for an ASCII control character (octets 0-31) or
       
  2210 		// an ASCII space character (octet 32), but allow ASCII linear white spce (octets 9,
       
  2211 		// 10, 13 and 32)
       
  2212 		if (currentChar < 33 && !(currentChar == KHorizTab || currentChar == KLinefeed 
       
  2213 			|| currentChar == KCarriageReturn || currentChar == KSpace))
       
  2214 			{
       
  2215 			return KErrCorrupt;
       
  2216 			}
       
  2217 		// Check for an ASCII delete character (octet 127)
       
  2218 		if (currentChar == 127)
       
  2219 			return KErrCorrupt;
       
  2220 		}
       
  2221 	return KErrNone;
       
  2222 	}
       
  2223 
       
  2224 TInt CWspHeaderWriter::EncodeContentTypeValue(THTTPHdrVal& aContentType) const
       
  2225 	{
       
  2226 	TInt encodedToken = aContentType.StrF().Index(WSPContentTypes::Table);
       
  2227 	if( encodedToken > KErrNotFound )
       
  2228 		{
       
  2229 		// Apply some WSP version control on encoded token
       
  2230 		switch (iCodec.GetWspVersion())
       
  2231 			{
       
  2232 			case CWspHeaderCodec::EVersion1_1:
       
  2233 				{
       
  2234 				if( encodedToken > 0x2D ) // Highest content-type encoding is 0x2D in v1.1
       
  2235 					encodedToken = KErrNotFound;
       
  2236 				} break;
       
  2237 			case CWspHeaderCodec::EVersion1_2:
       
  2238 				{
       
  2239 				if( encodedToken > 0x34 ) // Highest content-type encoding is 0x34 in v1.2
       
  2240 					encodedToken = KErrNotFound;
       
  2241 				} break;
       
  2242 			case CWspHeaderCodec::EVersion1_3:
       
  2243 				{
       
  2244 				if( encodedToken > 0x36 ) // Highest content-type encoding is 0x36 in v1.3
       
  2245 					encodedToken = KErrNotFound;
       
  2246 				} break;
       
  2247 			default: // version is 1.4 that can encode all content-types in string table
       
  2248 				break;
       
  2249 			}
       
  2250 		}
       
  2251 	return encodedToken;
       
  2252 	}
       
  2253 
       
  2254 TInt CWspHeaderWriter::EncodeParameterTokenValue(RStringF aParameterName) const
       
  2255 	{
       
  2256 	TInt encodedToken = aParameterName.Index(WSPParam::Table);
       
  2257 	if( encodedToken > KErrNotFound )
       
  2258 		{
       
  2259 		// Apply some WSP version control on encoded token
       
  2260 		switch (iCodec.GetWspVersion())
       
  2261 			{
       
  2262 			// Check for maximum encoding token for current WSP version
       
  2263 			case CWspHeaderCodec::EVersion1_1:
       
  2264 				{
       
  2265 				if( encodedToken > 0x08 ) // Highest parameter token encoding is 0x08 in v1.1
       
  2266 					encodedToken = KErrNotFound;
       
  2267 				} break;
       
  2268 			case CWspHeaderCodec::EVersion1_2:
       
  2269 				{
       
  2270 				if( encodedToken > 0x0B ) // Highest parameter token encoding is 0x0b in v1.2
       
  2271 					encodedToken = KErrNotFound;
       
  2272 				} break;
       
  2273 			case CWspHeaderCodec::EVersion1_3:
       
  2274 				{
       
  2275 				if( encodedToken > 0x10 ) // Highest parameter token encoding is 0x10 in v1.3
       
  2276 					encodedToken = KErrNotFound;
       
  2277 				} break;
       
  2278 			default: // version is 1.4 that can encode all parameter tokens in string table
       
  2279 				break;
       
  2280 			}
       
  2281 		}
       
  2282 	return encodedToken;
       
  2283 	}
       
  2284 
       
  2285 // Implementation of CWspDefaultHdrWriter
       
  2286 //-------------------------------------------------------------------------------
       
  2287 
       
  2288 CWspDefaultHdrWriter* CWspDefaultHdrWriter::NewL(RStringPool aStrPool)
       
  2289 	{
       
  2290 	return new(ELeave)CWspDefaultHdrWriter(aStrPool);
       
  2291 	}
       
  2292 
       
  2293 CWspDefaultHdrWriter* CWspDefaultHdrWriter::NewLC(RStringPool aStrPool)
       
  2294 	{
       
  2295 	CWspDefaultHdrWriter* self = CWspDefaultHdrWriter::NewL(aStrPool);
       
  2296 	CleanupStack::PushL(self);
       
  2297 	return self;
       
  2298 	}
       
  2299 
       
  2300 CWspDefaultHdrWriter::CWspDefaultHdrWriter(RStringPool aStrPool)
       
  2301 	: iStrPool(aStrPool)
       
  2302 	{
       
  2303 	}
       
  2304 
       
  2305 CWspDefaultHdrWriter::~CWspDefaultHdrWriter()
       
  2306 	{
       
  2307 	}
       
  2308 
       
  2309 void CWspDefaultHdrWriter::EncodeHeaderL(RHeaderField& aHeader)
       
  2310 	{
       
  2311 	THeaderFieldPartIter partIter = aHeader.PartsL();
       
  2312 	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
       
  2313 	CleanupStack::PushL(encoder);
       
  2314 	TInt partCount = 0;
       
  2315 	aHeader.BeginRawDataL();
       
  2316 	partIter.First();
       
  2317 	// Loop through all the parts and build up the raw data
       
  2318 	while (!partIter.AtEnd())
       
  2319 		{
       
  2320 		encoder->StartHeaderL(aHeader.Name().DesC());
       
  2321 		const CHeaderFieldPart* part = partIter();
       
  2322 		if (part != NULL)
       
  2323 			{
       
  2324 			++partCount;
       
  2325 			THTTPHdrVal value = part->Value();
       
  2326 			if (value.Type() == THTTPHdrVal::KStrFVal)
       
  2327 				encoder->AddTextStringL(value.StrF().DesC());
       
  2328 			else
       
  2329 				User::Leave(KErrCorrupt);
       
  2330 			}
       
  2331 
       
  2332 		HBufC8* buffer = encoder->EndHeaderL();
       
  2333 		CleanupStack::PushL(buffer);
       
  2334 		TInt startPos = 0;
       
  2335 		// If this is the first part then don't include the header name
       
  2336 		if (partCount == 1)
       
  2337 			startPos = (aHeader.Name().DesC().Length()) + 1;
       
  2338 		TPtrC8 data(buffer->Mid(startPos));
       
  2339 		aHeader.WriteRawDataL(data);
       
  2340 		CleanupStack::PopAndDestroy(buffer);
       
  2341 		++partIter;
       
  2342 		}
       
  2343 	aHeader.CommitRawData();
       
  2344 	CleanupStack::PopAndDestroy(encoder);
       
  2345 	}