applayerpluginsandutils/httpprotocolplugins/wspheadercodec/CWspHeaderWriter.cpp
changeset 0 b16258d2340f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerpluginsandutils/httpprotocolplugins/wspheadercodec/CWspHeaderWriter.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,2345 @@
+// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+// System Includes
+#include <wspstringconstants.h>
+#include <wspparamconstants.h>
+#include <wspcontenttypes.h>
+#include <wspregcontenttypes.h>
+#include <wspcharactersets.h>
+#include <wspstdconstants.h>
+#include <wsplanguages.h>
+#include <wsptypeconstants.h>
+
+// User Includes
+#include "cheaderfield.h"
+#include "cwspheaderwriter.h"
+
+const TInt KOffset = 1;				// Offset as the WspLanguages string table does not have 0x80 in it
+const TInt KShortIntLimit = 128;	// A short integer can be within the range of 0-127
+
+CWspHeaderWriter* CWspHeaderWriter::NewL(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
+	{
+	return new(ELeave)CWspHeaderWriter(aStrPool, aStrTable, aCodec);
+	}
+
+CWspHeaderWriter* CWspHeaderWriter::NewLC(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
+	{
+	CWspHeaderWriter* self = CWspHeaderWriter::NewL(aStrPool, aStrTable, aCodec);
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+CWspHeaderWriter::CWspHeaderWriter(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
+	: iStrPool(aStrPool), iStrTable(aStrTable), iCodec(aCodec)
+	{
+	}
+
+CWspHeaderWriter::~CWspHeaderWriter()
+	{
+	}
+
+void CWspHeaderWriter::EncodeHeaderL(RHeaderField& aHeader)
+	{
+	switch(aHeader.Name().Index(iStrTable))
+		{
+		case WSP::EAccept:
+			{
+			EncodeAcceptL(aHeader);
+			} break;
+		case WSP::EAcceptCharsetDep:
+		case WSP::EAcceptCharset:
+			{
+			EncodeAcceptCharsetL(aHeader);
+			} break;
+		case WSP::EAcceptEncodingDep:
+		case WSP::EAcceptEncoding:
+			{
+			EncodeAcceptEncodingL(aHeader);
+			} break;
+		case WSP::EAcceptLanguage:
+			{
+			EncodeAcceptLanguageL(aHeader);
+			} break;
+		case WSP::EAllow:
+			{
+			EncodeAllowL(aHeader);
+			} break;
+		case WSP::EAuthorization:
+			{
+			EncodeAuthorizationL(aHeader);
+			} break;
+		case WSP::EContentEncoding:
+			{
+			EncodeContentEncodingL(aHeader);
+			} break;
+		case WSP::EContentLanguage:
+			{
+			EncodeContentLanguageL(aHeader);
+			} break;
+		case WSP::EContentLocation:
+		case WSP::EFrom:
+		case WSP::EProfile:
+		case WSP::EReferer:
+		case WSP::EUpgrade:
+		case WSP::EUserAgent:
+		case WSP::EVia:
+			{
+			GenericEncodeTextStringL(aHeader);
+			} break;
+		case WSP::EContentMD5:
+			{
+			EncodeContentMD5L(aHeader);
+			} break;
+		case WSP::EContentRangeDep:
+		case WSP::EContentRange:
+			{
+			EncodeContentRangeL(aHeader);
+			} break;
+		case WSP::EContentType:
+			{
+			EncodeContentTypeL(aHeader);
+			} break;
+		case WSP::ECookie:
+			{
+			EncodeCookieL(aHeader);
+			} break;
+		case WSP::EDate:
+		case WSP::ELastModified:
+			{
+			GenericEncodeDateL(aHeader);
+			} break;
+		case WSP::EEncodingVersion:
+			{
+			EncodeEncodingVersionL(aHeader);
+			} break;
+		case WSP::EExpect:
+			{
+			EncodeExpectL(aHeader);
+			} break;
+		case WSP::EPragma:
+			{
+			EncodePragmaL(aHeader);
+			} break;
+		case WSP::EProfileDiff:
+			{
+			EncodeProfileDiffL(aHeader);
+			} break;
+		case WSP::ERange:
+			{
+			EncodeRangeL(aHeader);
+			} break;
+		case WSP::ETE:
+			{
+			EncodeTEL(aHeader);
+			} break;
+		case WSP::ETrailer:
+			{
+			EncodeTrailerL(aHeader);
+			} break;
+		case WSP::EWarning:
+			{
+			EncodeWarningL(aHeader);
+			} break;
+		case WSP::EXWapApplicationId:
+			{
+			EncodeXWapApplicationIdL(aHeader);
+			} break;
+		default:
+			User::Leave(KErrNotSupported);
+			break;
+		}
+	}
+
+
+void CWspHeaderWriter::EncodeAcceptL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	partIter.First();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	TInt partCount = 0;
+	TBool requireValueLength = EFalse;
+	aHeader.BeginRawDataL();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			TInt numParam = part->NumParameters();
+			if (numParam > 0)
+				{
+				requireValueLength = ETrue;
+				encoder->StartValueLengthL();
+				}
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				TInt typeValue = EncodeContentTypeValue(value);
+				if (typeValue < KShortIntLimit && typeValue > KErrNotFound)
+					encoder->AddShortIntL((TUint8)typeValue);
+				else if (typeValue == KErrNotFound)
+					{
+					TInt registeredValue = value.StrF().Index(WSPRegContentTypes::Table);
+					if (registeredValue > KErrNotFound)
+						{
+						if (!requireValueLength)
+							{
+							encoder->StartValueLengthL();
+							requireValueLength = ETrue;
+							}
+						const TInt KContentTypeOffset = 0x0201;	// Offset for the Registered Content Type value string table
+						encoder->AddLongIntL(registeredValue + KContentTypeOffset);
+						}
+					else if (registeredValue == KErrNotFound)
+						{
+						User::LeaveIfError(CheckTextString(value.StrF()));
+						encoder->AddTextStringL(value.StrF().DesC());
+						}
+					}
+
+				THeaderFieldParamIter paramIter = part->Parameters();
+				paramIter.First();
+				while (!paramIter.AtEnd())
+					{
+					const CHeaderFieldParam* param = paramIter();
+					if (param != NULL)
+						EncodeParameterL(*param, *encoder);
+					++paramIter;
+					}
+				if (requireValueLength)
+					encoder->EndValueLengthL();
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		// If there is more than one header part it is necessary to append the name of the
+		// header to the buffer
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeAcceptCharsetL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	partIter.First();
+	aHeader.BeginRawDataL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	TInt partCount = 0;
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		TBool requireValueLength = EFalse;
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			TInt numParam = part->NumParameters();
+			if (numParam > 0)
+				{
+				requireValueLength = ETrue;
+				encoder->StartValueLengthL();
+				}
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				// Check for '*' (Any-charset) and that the WSP version is greater than 1.2
+				if ((value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::EAny) 
+					&& (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_2))
+					{
+					encoder->AddTokenL(128);		// '*' is encoded as <Octet 128>
+					}
+				else
+					{
+					TInt charValue = GetCharacterSetValue(value.StrF());
+					switch(charValue)
+						{
+						case KErrNotFound:
+							{
+							User::LeaveIfError(CheckTextString(value.StrF()));
+							encoder->AddTextStringL(value.StrF().DesC());
+							} break;
+						default:
+							{
+							if (charValue < KShortIntLimit)
+								encoder->AddShortIntL((TUint8)charValue);
+							else
+								{
+								if (!requireValueLength)
+									{
+									encoder->StartValueLengthL();
+									requireValueLength = ETrue;
+									}
+								encoder->AddLongIntL(charValue);
+								}
+							} break;
+						}
+					}
+
+				// Check if we have any parameters
+				THeaderFieldParamIter paramIter = part->Parameters();
+				paramIter.First();
+				while (!paramIter.AtEnd())
+					{
+					const CHeaderFieldParam* param = paramIter();
+					THTTPHdrVal paramValue = param->Value();
+					HBufC8* qValue = EncodeQValueL(paramValue.StrF());
+					CleanupStack::PushL(qValue);
+					if (qValue != NULL)
+						encoder->AddDataL(*qValue);
+					++paramIter;
+					CleanupStack::PopAndDestroy(qValue);
+					}
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		// If we have a Q-value then we need to calculate the value-length
+		if (requireValueLength)
+			encoder->EndValueLengthL();
+		
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;		
+		// If there is more than one header part it is necessary to append the name of the
+		// header to the buffer
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeAcceptEncodingL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	partIter.First();
+	TInt partCount = 0;
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());	
+	aHeader.BeginRawDataL();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		TBool requireValueLength = EFalse;
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			TInt numParam = part->NumParameters();
+			if (numParam > 0)
+				{
+				requireValueLength = ETrue;
+				encoder->StartValueLengthL();
+				}
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				TInt encValue = value.StrF().Index(WSPStdConstants::Table);
+				// Check for '*' (Any-encoding) and that the WSP version is greater than 1.2
+				if ((encValue == WSPStdConstants::EAny) 
+					&& (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_2))
+					{
+					if (!requireValueLength)
+						{
+						encoder->StartValueLengthL();
+						requireValueLength = ETrue;
+						}
+					encoder->AddTokenL(131);				// '*' is encoded as <Octet 131>
+					}
+				else
+					{
+					switch(encValue)
+						{
+						case WSPStdConstants::EGzip:		// Gzip is encoded as <Octet 128>
+							{
+							encoder->AddTokenL(128);
+							} break;
+						case WSPStdConstants::ECompress:	// Compress is encoded as <Octet 129>
+							{
+							encoder->AddTokenL(129);
+							} break;
+						case WSPStdConstants::EDeflate:		// Deflate is encoded as <Octet 130>
+							{
+							encoder->AddTokenL(130);
+							} break;
+						default:
+							{
+							encoder->AddTokenTextL(value.StrF().DesC());
+							} break;
+						}
+					}
+			
+				THeaderFieldParamIter paramIter = part->Parameters();
+				paramIter.First();
+				while (!paramIter.AtEnd())
+					{
+					const CHeaderFieldParam* param = paramIter();
+					THTTPHdrVal paramValue = param->Value();
+					HBufC8* qValue = EncodeQValueL(paramValue.StrF());
+					CleanupStack::PushL(qValue);
+					if (qValue != NULL)
+						encoder->AddDataL(*qValue);
+					CleanupStack::PopAndDestroy(qValue);
+					++paramIter;
+					}
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		if (requireValueLength)
+			encoder->EndValueLengthL();
+		
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;	
+		// If there is more than one header part it is necessary to append the name of the
+		// header to the buffer
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeAcceptLanguageL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	partIter.First();
+	TInt partCount = 0;
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	aHeader.BeginRawDataL();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		TBool requireValueLength = EFalse;
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			TInt numParam = part->NumParameters();
+			if (numParam > 0)
+				{
+				requireValueLength = ETrue;
+				encoder->StartValueLengthL();
+				}
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				TInt langValue = value.StrF().Index(WSPLanguages::Table);
+				switch(langValue)
+					{
+					case WSPLanguages::EAnyLanguage:
+						{
+						encoder->AddTokenL(128);		// '*' (Any-language) is encoded as <Octet 128>
+						} break;
+					case KErrNotFound:
+						{
+						User::LeaveIfError(CheckTextString(value.StrF()));
+						encoder->AddTextStringL(value.StrF().DesC());
+						} break;
+					default:
+						{
+						if (langValue < KShortIntLimit)
+							encoder->AddShortIntL((TUint8)langValue);
+						else
+							{
+							if (!requireValueLength)
+								{
+								encoder->StartValueLengthL();
+								requireValueLength = ETrue;
+								}
+							encoder->AddLongIntL(langValue + KOffset);
+							}
+						} break;
+					}
+
+				THeaderFieldParamIter paramIter = part->Parameters();
+				paramIter.First();
+				while (!paramIter.AtEnd())
+					{
+					const CHeaderFieldParam* param = paramIter();
+					THTTPHdrVal paramValue = param->Value();
+					HBufC8* qValue = EncodeQValueL(paramValue.StrF());
+					CleanupStack::PushL(qValue);
+					if (qValue != NULL)
+						encoder->AddDataL(*qValue);
+					++paramIter;
+					CleanupStack::PopAndDestroy(qValue);
+					}
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		if (requireValueLength)
+			encoder->EndValueLengthL();
+		
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;	
+		// If there is more than one header part it is necessary to append the name of the
+		// header to the buffer
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeAllowL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	aHeader.BeginRawDataL();
+	TInt partCount = 0;
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				TUint8 allowNumber = 0;
+				TInt allowValue = value.StrF().Index(WSPTypeConstants::Table);
+				switch(allowValue)
+					{
+					case WSPTypeConstants::EGet:
+						{
+						allowNumber = 64;		// Get is encoded as 0x40
+						} break;
+					case WSPTypeConstants::EOptions:
+						{
+						allowNumber = 65;		// Options is encoded as 0x41
+						} break;
+					case WSPTypeConstants::EHead:
+						{
+						allowNumber = 66;		// Head is encoded as 0x42
+						} break;
+					case WSPTypeConstants::EDelete:
+						{
+						allowNumber = 67;		// Delete is encoded as 0x43
+						} break;
+					case WSPTypeConstants::ETrace:
+						{
+						allowNumber = 68;		// Trace is encoded as 0x44
+						} break;
+					case WSPTypeConstants::EPost:
+						{
+						allowNumber = 96;		// Post is encoded as 0x60
+						} break;
+					case WSPTypeConstants::EPut:
+						{
+						allowNumber = 97;		// Put is encoded as 0x61
+						} break;
+					default:
+						User::Leave(KErrNotFound);
+						break;
+					}
+				encoder->AddShortIntL(allowNumber);
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeAuthorizationL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				encoder->StartValueLengthL();
+				// Check to see if the first part is 'Basic'
+				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::EBasic)
+					{
+					// If it is, then encode Basic as <Octet 128> and then iterate through the
+					// following parts which should contain the 'User-ID' and 'Password'
+					encoder->AddTokenL(128);
+					++partIter;
+					while (!partIter.AtEnd())
+						{
+						value = partIter()->Value();
+						if(value.Type() == THTTPHdrVal::KStrFVal)
+							{
+							User::LeaveIfError(CheckTextString(value.StrF()));
+							encoder->AddTextStringL(value.StrF().DesC());
+							++partIter;
+							}
+						else
+							User::Leave(KErrCorrupt);
+						}
+					}
+				// Otherwise, the first part is an 'Authentication-scheme' with zero or more parameters
+				else
+					{
+					encoder->AddTokenTextL(value.StrF().DesC());
+					THeaderFieldParamIter paramIter = part->Parameters();
+					paramIter.First();
+					while (!paramIter.AtEnd())
+						{
+						const CHeaderFieldParam* param = paramIter();
+						if (param != NULL)
+							EncodeParameterL(*param, *encoder);
+						++paramIter;
+						}
+					}
+				encoder->EndValueLengthL();
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		aHeader.BeginRawDataL();	
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		aHeader.CommitRawData();
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeContentEncodingL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	aHeader.BeginRawDataL();
+	TInt partCount = 0;
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				TInt encValue = value.StrF().Index(WSPStdConstants::Table);
+				switch(encValue)
+					{
+					case WSPStdConstants::EGzip:
+						{
+						encoder->AddTokenL(128);		// Gzip is encoded as <Octet 128>
+						} break;
+					case WSPStdConstants::ECompress:
+						{
+						encoder->AddTokenL(129);		// Compress is encoded as <Octet 129>
+						} break;
+					case WSPStdConstants::EDeflate:
+						{
+						encoder->AddTokenL(130);		// Deflate is encoded as <Octet 130>
+						} break;
+					default:
+						{
+						encoder->AddTokenTextL(value.StrF().DesC());
+						} break;
+					}
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeContentLanguageL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	partIter.First();
+	TInt partCount = 0;
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	aHeader.BeginRawDataL();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				TInt langValue = value.StrF().Index(WSPLanguages::Table);
+				switch(langValue)
+					{
+					case WSPLanguages::EAnyLanguage:
+						{
+						encoder->AddTokenL(128);		// '*' (Any-language) is encoded as <Octet 128>
+						} break;
+					case KErrNotFound:
+						{
+						encoder->AddTokenTextL(value.StrF().DesC());
+						} break;
+					default:
+						{
+						if (langValue < KShortIntLimit)
+							encoder->AddShortIntL((TUint8)langValue);
+						else
+							encoder->AddLongIntL(langValue + KOffset);
+						} break;
+					}
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeContentMD5L(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TBool requireValueLength = EFalse;
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				encoder->StartValueLengthL();
+				encoder->AddDataL(value.StrF().DesC());
+				requireValueLength = ETrue;
+				}
+			else
+				User::Leave(KErrCorrupt);
+
+			if (requireValueLength)
+				encoder->EndValueLengthL();
+
+			aHeader.BeginRawDataL();	
+			HBufC8* buffer = encoder->EndHeaderL();
+			CleanupStack::PushL(buffer);
+			TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+			aHeader.WriteRawDataL(data);
+			CleanupStack::PopAndDestroy(buffer);
+			aHeader.CommitRawData();
+			}
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeContentRangeL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KTIntVal)
+				{
+				encoder->StartValueLengthL();
+				encoder->AddUintVarL(value);
+				++partIter;
+				if (!partIter.AtEnd())
+					{
+					value = partIter()->Value();
+					if (value.Type() == THTTPHdrVal::KStrFVal)
+						{
+						// Check for '*' (Any-encoding) and that the WSP version is greater than 1.2
+						if ((value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::EAny)
+							&& (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_2))
+							{
+							encoder->AddTokenL(128);	// '*' is encoded as <Octet 128>
+							}
+						}
+					if (value.Type() == THTTPHdrVal::KTIntVal)
+						encoder->AddUintVarL(value);
+					}
+				encoder->EndValueLengthL();
+				}
+			else
+				User::Leave(KErrCorrupt);
+
+			aHeader.BeginRawDataL();	
+			HBufC8* buffer = encoder->EndHeaderL();
+			CleanupStack::PushL(buffer);
+			TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+			aHeader.WriteRawDataL(data);
+			CleanupStack::PopAndDestroy(buffer);
+			aHeader.CommitRawData();
+			}
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeContentTypeL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	TBool requireValueLength = EFalse;
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			TInt numParam = part->NumParameters();
+			if (numParam > 0)
+				{
+				requireValueLength = ETrue;
+				encoder->StartValueLengthL();
+				}
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				TInt typeValue = EncodeContentTypeValue(value);
+				if (typeValue < KShortIntLimit && typeValue > KErrNotFound)
+					encoder->AddShortIntL((TUint8)typeValue);
+				else if (typeValue == KErrNotFound)
+					{
+					TInt registeredValue = value.StrF().Index(WSPRegContentTypes::Table);
+					if (registeredValue > KErrNotFound)
+						{
+						if (!requireValueLength)
+							{
+							encoder->StartValueLengthL();
+							requireValueLength = ETrue;
+							}
+						const TInt KContentTypeOffset = 0x0201;	// Offset for the Registered Content Type value string table
+						encoder->AddLongIntL(registeredValue + KContentTypeOffset);
+						}
+					else if (registeredValue == KErrNotFound)
+						{
+						User::LeaveIfError(CheckTextString(value.StrF()));
+						encoder->AddTextStringL(value.StrF().DesC());
+						}
+					}
+				// check for params and append to temporary buffer
+				THeaderFieldParamIter paramIter = part->Parameters();
+				paramIter.First();
+				while (!paramIter.AtEnd())
+					{
+					const CHeaderFieldParam* param = paramIter();
+					if (param != NULL)
+						EncodeParameterL(*param, *encoder);
+					++paramIter;
+					}
+
+				if (requireValueLength)
+					encoder->EndValueLengthL();
+
+				aHeader.BeginRawDataL();	
+				HBufC8* buffer = encoder->EndHeaderL();
+				CleanupStack::PushL(buffer);
+				TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+				aHeader.WriteRawDataL(data);
+				CleanupStack::PopAndDestroy(buffer);
+				aHeader.CommitRawData();
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeCookieL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			// Encode the first part which is the Cookie-version value
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				encoder->StartValueLengthL();
+				TUint8 versionValue = EncodeVersionValueL(value.StrF());
+				if (versionValue == 0)
+					{
+					User::LeaveIfError(CheckTextString(value.StrF()));
+					encoder->AddTextStringL(value.StrF().DesC());
+					}
+				else
+					encoder->AddShortIntL(versionValue);
+
+				// Then move to the next part and iterate through all the parts that follow, appending
+				// the parameters if any exist
+				++partIter;
+				while (!partIter.AtEnd())
+					{
+					CWspHeaderEncoder* cookieEncoder = CWspHeaderEncoder::NewL();
+					CleanupStack::PushL(cookieEncoder);
+					value = partIter()->Value();	// The first part is the Cookie-Name
+					if (value.Type() == THTTPHdrVal::KStrFVal)
+						{
+						cookieEncoder->StartHeaderL((TUint8)token);
+						cookieEncoder->StartValueLengthL();
+						User::LeaveIfError(CheckTextString(value.StrF()));
+						cookieEncoder->AddTextStringL(value.StrF().DesC());
+						++partIter;
+						part = partIter();
+						value = partIter()->Value();	// The second part is the Cookie-Value
+						if (value.Type() == THTTPHdrVal::KStrFVal)
+							{
+							User::LeaveIfError(CheckTextString(value.StrF()));
+							cookieEncoder->AddTextStringL(value.StrF().DesC());
+							THeaderFieldParamIter paramIter = part->Parameters();	// Now check for any parameters
+							paramIter.First();
+							while (!paramIter.AtEnd())
+								{
+								const CHeaderFieldParam* param = paramIter();
+								if (param != NULL)
+									EncodeParameterL(*param, *cookieEncoder);
+								++paramIter;
+								}
+							}
+						else
+							User::Leave(KErrCorrupt);
+
+						cookieEncoder->EndValueLengthL();
+						HBufC8* cookieBuffer = cookieEncoder->EndHeaderL();
+						CleanupStack::PushL(cookieBuffer);
+						// Remove the header name from the buffer and then check if 
+						// the first byte is equal to 31 i.e. a length quote, and if so remove it
+						TInt offset = 1;
+						if (cookieBuffer->Des()[1] == 31)
+							++offset;
+						HBufC8* data = cookieBuffer->Mid(offset).AllocL();
+						CleanupStack::PushL(data);
+						encoder->AddDataL(*data);
+						CleanupStack::PopAndDestroy(2, cookieBuffer);		// data. cookieBuffer
+						}
+					++partIter;
+					part = partIter();
+					CleanupStack::PopAndDestroy(cookieEncoder);
+					}
+				encoder->EndValueLengthL();
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}	
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+		aHeader.BeginRawDataL();
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		aHeader.CommitRawData();
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeEncodingVersionL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)		// There is a version-value in the first part
+				{
+				TUint8 versionValue = EncodeVersionValueL(value.StrF());
+				if (versionValue == 0)
+					{
+					User::LeaveIfError(CheckTextString(value.StrF()));
+					encoder->AddTextStringL(value.StrF().DesC());
+					}
+				else
+					encoder->AddShortIntL(versionValue);
+				}
+			else if (value.Type() == THTTPHdrVal::KTIntVal)	// The first part is NOT a version-value but an int
+				{
+				encoder->StartValueLengthL();
+				if (value.Int() < KShortIntLimit)
+					encoder->AddShortIntL((TUint8)value);
+				else
+					User::Leave(KErrCorrupt);
+
+				++partIter;
+				if (!partIter.AtEnd())
+					{
+					value = partIter()->Value();
+					if (value.Type() == THTTPHdrVal::KStrFVal)
+						{
+						TUint8 versionValue = EncodeVersionValueL(value.StrF());
+						if (versionValue == 0)
+							{
+							User::LeaveIfError(CheckTextString(value.StrF()));
+							encoder->AddTextStringL(value.StrF().DesC());
+							}
+						else
+							encoder->AddShortIntL(versionValue);
+						}
+					}
+				encoder->EndValueLengthL();
+				}
+			else
+				User::Leave(KErrCorrupt);
+
+			aHeader.BeginRawDataL();	
+			HBufC8* buffer = encoder->EndHeaderL();
+			CleanupStack::PushL(buffer);
+			TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+			aHeader.WriteRawDataL(data);
+			CleanupStack::PopAndDestroy(buffer);
+			aHeader.CommitRawData();
+			}
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeExpectL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::E100Continue)
+					encoder->AddTokenL(128);		// 100-continue is encoded as <Octet 128>
+				else
+					{
+					encoder->StartValueLengthL();
+					while (!partIter.AtEnd())
+						{
+						value = partIter()->Value();
+						if(value.Type() == THTTPHdrVal::KStrFVal)
+							{
+							TPtrC8 valueDes(value.StrF().DesC());
+							if (valueDes[0] == 0x22)	// Check if we have a quoted-string
+								{
+								User::LeaveIfError(CheckTextString(value.StrF()));
+								encoder->AddTextStringL(value.StrF().DesC());
+								}
+							else
+								encoder->AddTokenTextL(value.StrF().DesC());
+
+							THeaderFieldParamIter paramIter = part->Parameters();
+							paramIter.First();
+							while (!paramIter.AtEnd())
+								{
+								const CHeaderFieldParam* param = paramIter();
+								if (param != NULL)
+									EncodeParameterL(*param, *encoder);
+								++paramIter;
+								}
+							++partIter;
+							part = partIter();
+							}
+						else
+							User::Leave(KErrCorrupt);
+						}
+					encoder->EndValueLengthL();
+					}
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		aHeader.BeginRawDataL();	
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		aHeader.CommitRawData();
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodePragmaL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	partIter.First();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TBool requireValueLength = EFalse;
+	TInt token = EncodeFieldName(aHeader.Name());
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::ENoCache)
+					encoder->AddTokenL(128);		// 'No-cache' is encoded as <Octet 128>
+				else
+					{
+					THeaderFieldParamIter paramIter = part->Parameters();
+					paramIter.First();
+					while (!paramIter.AtEnd())
+						{
+						const CHeaderFieldParam* param = paramIter();
+						if (param != NULL)
+							{
+							encoder->StartValueLengthL();
+							EncodeParameterL(*param, *encoder);
+							requireValueLength = ETrue;
+							}
+						++paramIter;
+						}
+					}
+				if (requireValueLength)
+					encoder->EndValueLengthL();
+
+				aHeader.BeginRawDataL();	
+				HBufC8* buffer = encoder->EndHeaderL();
+				CleanupStack::PushL(buffer);
+				TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+				aHeader.WriteRawDataL(data);
+				CleanupStack::PopAndDestroy(buffer);
+				aHeader.CommitRawData();
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+	
+void CWspHeaderWriter::EncodeProfileDiffL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt partCount = 0;
+	aHeader.BeginRawDataL();
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				encoder->StartValueLengthL();
+				encoder->AddDataL(value.StrF().DesC());
+				encoder->EndValueLengthL();
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+			
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeRangeL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	TInt partCount = 0;
+	aHeader.BeginRawDataL();
+	partIter.First();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				encoder->StartValueLengthL();
+				TInt rangeValue = value.StrF().Index(WSPStdConstants::Table);
+				switch (rangeValue)
+					{
+					case WSPStdConstants::EByteRange:
+						{
+						encoder->AddTokenL(128);	// 'Byte-range' is encoded as <Octet 128>
+						} break;
+					case WSPStdConstants::ESuffixByteRange:
+						{
+						encoder->AddTokenL(129);	// 'Suffix-byte-range' is encoded as <Octet 129>
+						} break;
+					default:
+						User::Leave(KErrCorrupt);
+					}
+				// Iterate through the parts that follow
+				++partIter;
+				while (!partIter.AtEnd())
+					{
+					value = partIter()->Value();
+					if(value.Type() == THTTPHdrVal::KTIntVal)
+						{
+						encoder->AddUintVarL(value);
+						++partIter;
+						}
+					else if(value.Type() == THTTPHdrVal::KStrFVal)
+						{
+						// Found the next header
+						break;
+						}
+					else
+						User::Leave(KErrCorrupt);
+					}
+				encoder->EndValueLengthL();
+				}
+			else
+				User::Leave(KErrCorrupt);			
+			}
+
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeTEL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	TBool requireValueLength = EFalse;
+	aHeader.BeginRawDataL();
+	TInt partCount = 0;
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			TInt numParam = part->NumParameters();
+			if (numParam > 0)
+				{
+				encoder->StartValueLengthL();
+				requireValueLength = ETrue;
+				}
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::ETrailers)
+					encoder->AddTokenL(129);		// 'Trailers' is encoded as <Octet 129>
+				else
+					{
+					if (!requireValueLength)
+						{
+						encoder->StartValueLengthL();
+						requireValueLength = ETrue;
+						}
+					TInt encValue = value.StrF().Index(WSPStdConstants::Table);
+					switch(encValue)
+						{
+						case WSPStdConstants::EChunked:
+							{
+							encoder->AddTokenL(130);		// 'Chunked' is encoded as <Octet 130>
+							} break;
+						case WSPStdConstants::EIdentity:
+							{
+							encoder->AddTokenL(131);		// 'Identity' is encoded as <Octet 131>
+							} break;
+						case WSPStdConstants::EGzip:
+							{
+							encoder->AddTokenL(132);		// 'Gzip' is encoded as <Octet 132>
+							} break;
+						case WSPStdConstants::ECompress:
+							{
+							encoder->AddTokenL(133);		// 'Compress' is encoded as <Octet 133>
+							} break;
+						case WSPStdConstants::EDeflate:
+							{
+							encoder->AddTokenL(134);		// 'Deflate' is encoded as <Octet 134>
+							} break;
+						default:
+							{
+							encoder->AddTokenTextL(value.StrF().DesC());
+							} break;
+						}
+
+					THeaderFieldParamIter paramIter = part->Parameters();
+					paramIter.First();
+					// Encode any parameters that exist.
+					// A parameter consists of a Q-token and a Q-value
+					while (!paramIter.AtEnd())
+						{
+						const CHeaderFieldParam* param = paramIter();
+						if (param != NULL)			
+							EncodeParameterL(*param, *encoder);
+						++paramIter;
+						}
+					if (requireValueLength)
+						encoder->EndValueLengthL();
+					}
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeTrailerL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	TInt partCount = 0;
+	aHeader.BeginRawDataL();
+	partIter.First();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				TInt headerNameVal = EncodeFieldName(value.StrF());
+				if (headerNameVal < KShortIntLimit && headerNameVal > KErrNotFound)
+					encoder->AddShortIntL((TUint8)headerNameVal);
+				else if (headerNameVal > 127)
+					encoder->AddLongIntL(headerNameVal);
+				else
+					encoder->AddTokenTextL(value.StrF().DesC());
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeWarningL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KTIntVal)
+				{
+				TUint8 warningNumber = 0;
+				switch(value)
+					{
+					case 110:
+						{
+						warningNumber = 10;		// Warning code 110 is encoded as <Octet 10>
+						} break;
+					case 111:
+						{
+						warningNumber = 11;		// Warning code 111 is encoded as <Octet 11>
+						} break;
+					case 112:
+						{
+						warningNumber = 12;		// Warning code 112 is encoded as <Octet 12>
+						} break;
+					case 113:
+						{
+						warningNumber = 13;		// Warning code 113 is encoded as <Octet 13>
+						} break;
+					case 199:
+					case 299:
+						{
+						warningNumber = 99;		// Warning codes 199 and 299 are encoded as <Octet 99>
+						} break;
+					case 214:
+						{
+						warningNumber = 14;		// Warning code 214 is encoded as <Octet 14>
+						} break;
+					default:
+						break;
+					}
+
+				++partIter;
+				if (partIter.AtEnd())	// Check to see if we have only one part
+					encoder->AddShortIntL(warningNumber);
+				else
+					{
+					encoder->StartValueLengthL();			// If there is more than one part then it is
+					encoder->AddShortIntL(warningNumber);	// necessary to work out the value-length
+					while (!partIter.AtEnd())
+						{
+						value = partIter()->Value();
+						if(value.Type() == THTTPHdrVal::KStrFVal)
+							{
+							User::LeaveIfError(CheckTextString(value.StrF()));
+							encoder->AddTextStringL(value.StrF().DesC());
+							++partIter;
+							}
+						else
+							User::Leave(KErrCorrupt);
+						}
+					encoder->EndValueLengthL();
+					}
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+		aHeader.BeginRawDataL();	
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		aHeader.CommitRawData();
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeXWapApplicationIdL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				User::LeaveIfError(CheckTextString(value.StrF()));
+				encoder->AddTextStringL(value.StrF().DesC());
+				}
+			else if (value.Type() == THTTPHdrVal::KTIntVal)
+				{
+				if (value.Int() < KShortIntLimit)
+					encoder->AddShortIntL((TUint8)(value.Int()));
+				else
+					encoder->AddLongIntL(value.Int());
+				}
+			else
+				User::Leave(KErrCorrupt);
+
+			HBufC8* buffer = encoder->EndHeaderL();
+			CleanupStack::PushL(buffer);
+			TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+			aHeader.BeginRawDataL();
+			aHeader.WriteRawDataL(data);
+			CleanupStack::PopAndDestroy(buffer);
+			aHeader.CommitRawData();
+			}
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+
+//
+// Generic methods
+//
+
+void CWspHeaderWriter::GenericEncodeDateL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	partIter.First();
+	if (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KDateVal)
+				{
+				encoder->AddDateL(value.DateTime());
+				HBufC8* buffer = encoder->EndHeaderL();
+				CleanupStack::PushL(buffer);
+				TPtrC8 data(buffer->Mid(EncodeHeaderNameL(aHeader)));
+				aHeader.BeginRawDataL();
+				aHeader.WriteRawDataL(data);
+				CleanupStack::PopAndDestroy(buffer);
+				aHeader.CommitRawData();
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+		}
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::GenericEncodeTextStringL(RHeaderField& aHeader) const
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	aHeader.BeginRawDataL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt token = EncodeFieldName(aHeader.Name());
+	TInt partCount = 0;
+	partIter.First();
+	while (!partIter.AtEnd())
+		{
+		if (token == KErrNotFound)
+			encoder->StartHeaderL(aHeader.Name().DesC());
+		else
+			encoder->StartHeaderL((TUint8)token);
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				{
+				User::LeaveIfError(CheckTextString(value.StrF()));
+				encoder->AddTextStringL(value.StrF().DesC());
+				}
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		if (partCount == 1)
+			startPos = EncodeHeaderNameL(aHeader);
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}
+
+void CWspHeaderWriter::EncodeParameterL(const CHeaderFieldParam& aHeaderFieldParam, CWspHeaderEncoder& aEncoder) const
+	{
+	THTTPHdrVal value = aHeaderFieldParam.Value();
+	TInt paramIndex = EncodeParameterTokenValue(aHeaderFieldParam.Name());
+	if (paramIndex == KErrNotFound)		// This is an untyped parameter
+		{
+		// Append the name as a string
+		aEncoder.AddTokenTextL(aHeaderFieldParam.Name().DesC());
+
+		// Append the param value
+		switch(value.Type())
+			{
+			case THTTPHdrVal::KTIntVal:
+				{
+				if (value.Int() < KShortIntLimit)
+					aEncoder.AddShortIntL((TUint8)(value.Int()));
+				else
+					aEncoder.AddLongIntL(value.Int());
+				} break;
+			case THTTPHdrVal::KStrFVal:
+				{
+				User::LeaveIfError(CheckTextString(value.StrF()));
+				aEncoder.AddTextStringL(value.StrF().DesC());
+				} break;
+			default:
+				{
+				User::Leave(KErrCorrupt);
+				} break;
+			}
+		}
+	else	// This is a typed parameter
+		{
+		// Check encoding version and adjust token as neccessary
+		if (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_3)
+			{
+			switch (paramIndex)
+				{
+				case 0x05:
+					paramIndex = 0x17;	// Name-token is encoded as 0x17 in WSP version 1.4
+					break;
+				case 0x06:
+					paramIndex = 0x18;	// Filename-token is encoded as 0x18 in WSP version 1.4
+					break;
+				case 0x0A:
+					paramIndex = 0x19;	// Start-token is encoded as 0x19 in WSP version 1.4
+					break;
+				case 0x0B:
+					paramIndex = 0x1A;	// Start-info-token is encoded as 0x1A in WSP version 1.4
+					break;
+				case 0x0C:
+					paramIndex = 0x1B;	// Comment-token is encoded as 0x1B in WSP version 1.4
+					break;
+				case 0x0D:
+					paramIndex = 0x1C;	// Domain-token is encoded as 0x1C in WSP version 1.4
+					break;
+				case 0x0F:
+					paramIndex = 0x1D;	// Path-token is encoded as 0x1D in WSP version 1.4
+					break;
+				default:
+					break;
+				}
+			}
+		// Append the name as an encoded value
+		aEncoder.AddShortIntL((TUint8)paramIndex);
+		
+		// Append the param value
+		switch(paramIndex)
+			{
+			case WSPParam::EQ:
+				{
+				HBufC8* qValue = EncodeQValueL(value.StrF());
+				if (qValue != NULL)
+					{
+					CleanupStack::PushL(qValue);
+					aEncoder.AddDataL(*qValue);
+					CleanupStack::PopAndDestroy(qValue);
+					}
+				} break;
+			case WSPParam::ECharset:
+				{
+				if (value.StrF().Index(WSPStdConstants::Table) == WSPStdConstants::EAny)
+					aEncoder.AddTokenL(128);	// '*' (Any-charset) is encoded as <Octet 128> 
+				else
+					{
+					TInt charValue = GetCharacterSetValue(value.StrF());
+					User::LeaveIfError(charValue);
+					if (charValue < KShortIntLimit)
+						aEncoder.AddShortIntL((TUint8)charValue);
+					else
+						aEncoder.AddLongIntL(charValue);
+					}
+				} break;
+			case WSPParam::ELevel:
+				{
+				TUint8 versionValue = EncodeVersionValueL(value.StrF());
+				if (versionValue == 0)
+					{
+					User::LeaveIfError(CheckTextString(value.StrF()));
+					aEncoder.AddTextStringL(value.StrF().DesC());
+					}
+				else
+					aEncoder.AddShortIntL(versionValue);
+				} break;
+			case WSPParam::EType:
+			case WSPParam::EContentTypeType:
+			case WSPParam::ESize:
+			case WSPParam::EPadding:
+			case WSPParam::ESEC:
+			case WSPParam::EMaxAge:
+				{
+				if (value.Int() < KShortIntLimit)
+					aEncoder.AddShortIntL((TUint8)value.Int());
+				else
+					aEncoder.AddLongIntL(value.Int());
+				} break;
+			case WSPParam::ENameDep:
+			case WSPParam::EFilenameDep:
+			case WSPParam::EStartDep:
+			case WSPParam::EStartInfoDep:
+			case WSPParam::ECommentDep:
+			case WSPParam::EDomainDep:
+			case WSPParam::EPathDep:
+			case WSPParam::EName:
+			case WSPParam::EFilename:
+			case WSPParam::EStart:
+			case WSPParam::EStartInfo:
+			case WSPParam::EComment:
+			case WSPParam::EDomain:
+			case WSPParam::EPath:
+			case WSPParam::EMAC:
+				{
+				TPtrC8 valueDes(value.StrF().DesC());
+				if ((iCodec.GetWspVersion() < CWspHeaderCodec::EVersion1_4) || 
+					(valueDes.Length() == 0) ||
+					(valueDes[0] == 0x22))		// Check if we have a quoted-string
+					{
+					User::LeaveIfError(CheckTextString(value.StrF()));
+					aEncoder.AddTextStringL(valueDes);
+					}
+				else
+					{
+					User::LeaveIfError(CheckTokenText(value.StrF()));
+					aEncoder.AddTokenTextL(valueDes);
+					}
+				} break;
+			case WSPParam::EDifferences:
+				{
+				TInt headerNameVal = EncodeFieldName(value.StrF());
+				if (headerNameVal < KShortIntLimit && headerNameVal > KErrNotFound)
+					aEncoder.AddShortIntL((TUint8)headerNameVal);
+				else
+					aEncoder.AddTokenTextL(value.StrF().DesC());
+				} break;
+			case WSPParam::ECreationDate:
+			case WSPParam::EModificationDate:
+			case WSPParam::EReadDate:
+				{
+				aEncoder.AddDateL(value.DateTime());
+				} break;
+			case WSPParam::ESecure:
+				{
+				aEncoder.AddTokenL(0);
+				} break;
+			default:
+				{
+				aEncoder.AddTokenTextL(value.StrF().DesC());
+				} break;
+			}
+		}
+	}
+
+TInt CWspHeaderWriter::GetCharacterSetValue(RStringF aCharSet) const
+	{
+	TInt value = KErrNotFound;
+	switch(aCharSet.Index(WSPCharacterSets::Table))
+		{
+		case WSPCharacterSets::EBig5:
+			{
+			value =  0x07EA;		// Character set big5 is encoded as 0x07EA
+			} break;
+		case WSPCharacterSets::EIso10646ucs2:
+			{
+			value =  0x03E8;		// Character set iso-10646-ucs-2 is encoded as 0x03E8 
+			} break;
+		case WSPCharacterSets::EIso88591:
+			{
+			value =  0x04;		// Character set iso-8859-1 is encoded as 0x04
+			} break;
+		case WSPCharacterSets::EIso88592:
+			{
+			value =  0x05;		// Character set iso-8859-2 is encoded as 0x05
+			} break;
+		case WSPCharacterSets::EIso88593:
+			{
+			value =  0x06;		// Character set iso-8859-3 is encoded as 0x06
+			} break;
+		case WSPCharacterSets::EIso88594:
+			{
+			value =  0x07;		// Character set iso-8859-4 is encoded as 0x07
+			} break;
+		case WSPCharacterSets::EIso88595:
+			{
+			value =  0x08;		// Character set iso-8859-5 is encoded as 0x08
+			} break;
+		case WSPCharacterSets::EIso88596:
+			{
+			value =  0x09;		// Character set iso-8859-6 is encoded as 0x09
+			} break;
+		case WSPCharacterSets::EIso88597:
+			{
+			value =  0x0A;		// Character set iso-8859-9 is encoded as 0x0A
+			} break;
+		case WSPCharacterSets::EIso88598:
+			{
+			value =  0x0B;		// Character set iso-8859-8 is encoded as 0x0B
+			} break;
+		case WSPCharacterSets::EIso88599:
+			{
+			value =  0x0C;		// Character set iso-8859-9 is encoded as 0x0C
+			} break;
+		case WSPCharacterSets::EShiftJIS:
+			{
+			value =  0x11;		// Character set shift_JIS is encoded as 0x11
+			} break;
+		case WSPCharacterSets::EUsAscii:
+			{
+			value =  0x03;		// Character set us-ascii is encoded as 0x03
+			} break;
+		case WSPCharacterSets::EUtf8:
+		case WSPCharacterSets::EGsmDefaultAlphabet:
+			{
+			value = 0x6A;		// Character sets utf-8 and gsm-default-alphabet are
+			} break;			// encoded as 0x6A
+		default:
+			// Use default value of KErrNotFound
+			break;
+		}
+	return value;
+	}
+
+HBufC8* CWspHeaderWriter::EncodeQValueL(RStringF aQValue) const
+	{
+	TInt decPointPos = aQValue.DesC().Locate('.');
+	if (decPointPos != KErrNotFound)
+		{
+		if ((decPointPos + 1) >= aQValue.DesC().Length())
+			User::Leave(KErrCorrupt);
+		TPtrC8 decValue(aQValue.DesC().Mid(decPointPos + 1));
+		TLex8 intConvertDes(decValue);
+		TInt convertedInt = 0;
+		if (intConvertDes.Val(convertedInt) != KErrNone)
+			User::Leave(KErrCorrupt);
+		switch(decValue.Length())
+			{
+			case 1:
+				convertedInt *= 10;
+			case 2:
+				++convertedInt;
+				break;
+			case 3:
+				convertedInt += 100;
+				break;
+			default:
+				User::Leave(KErrCorrupt);
+				break;
+			}
+		return TWspPrimitiveEncoder::UintVarL(convertedInt);
+		}
+	return NULL;
+	}
+
+TUint8 CWspHeaderWriter::EncodeVersionValueL(RStringF aVersionValue) const
+	{
+	TPtrC8 version(aVersionValue.DesC());
+	TInt versionLength = version.Length();
+	if (versionLength == 0)
+		User::Leave(KErrCorrupt);
+	TInt decimalPos = version.Locate('.');
+	TUint8 majorVersion = 0;
+	TUint8 minorVersion = 0x0F;
+	if (decimalPos != KErrNotFound)
+		{
+		if ((decimalPos + 1) == versionLength)
+			User::Leave(KErrCorrupt);
+		TPtrC8 minorDes(version.Mid(decimalPos + 1));
+		TLex8 convertMinor(minorDes);
+		TInt convertedMinor = 0;
+		if (convertMinor.Val(convertedMinor) != KErrNone)
+			User::Leave(KErrCorrupt);
+		if (convertedMinor > 14)	// The minor version number must be within the range 0-14
+			return 0;
+		else
+			minorVersion = (TUint8)convertedMinor;
+		}
+	TPtrC8 majorDes;
+	if (decimalPos == KErrNotFound)
+		majorDes.Set(version);
+	else
+		majorDes.Set(version.Left(decimalPos));
+
+	TLex8 convertMajor(majorDes);
+	TInt convertedInt = 0;
+	if (convertMajor.Val(convertedInt) != KErrNone)
+		User::Leave(KErrCorrupt);
+	if (convertedInt > 7)			// The major version has a maximum value of 7
+		return 0;
+	else if (convertedInt > 0)		// and a minimum value of 1
+		majorVersion = (TUint8)convertedInt;
+	else
+		User::Leave(KErrCorrupt);
+		
+	majorVersion <<= 4;								// Shift the bits across by four places so that
+													// they are the most significant bits
+	return (TUint8)(majorVersion | minorVersion);
+	}
+
+TInt CWspHeaderWriter::EncodeFieldName(RStringF aFieldName) const
+	{
+	TInt fieldName = aFieldName.Index(iStrTable);
+	const CWspHeaderCodec::TWspVersion wspVersion = iCodec.GetWspVersion();
+
+	// Check WSP version against encoded ranges
+	switch(wspVersion)
+		{
+		case CWspHeaderCodec::EVersion1_1:
+			{
+			if(fieldName > 0x2E) // Highest header encoding is 0x2E in v1.1
+				fieldName = KErrNotFound;
+			} break;
+		case CWspHeaderCodec::EVersion1_2:
+			{
+			if(fieldName > 0x37) // Highest header encoding is 0x2E in v1.2
+				fieldName = KErrNotFound;
+			} break;
+		case CWspHeaderCodec::EVersion1_3:
+			{
+			if(fieldName > 0x43) // Highest header encoding is 0x2E in v1.3
+				fieldName = KErrNotFound;
+			} break;
+		default: // version is 1.4 that can encode everything
+			break;
+		}
+
+	// Make any value changes based on WSP version
+	TInt name = fieldName;
+	switch(fieldName)
+		{
+		case WSP::EAcceptCharsetDep:
+		case WSP::EAcceptCharset:
+			{
+			if (wspVersion < CWspHeaderCodec::EVersion1_3)
+				name = 0x01;		// Version 1.1 of Accept-Charset is encoded as 0x01
+			else
+				name = 0x3B;		// The current version (1.3) of Accept-Charset is encoded as 0x3B
+			} break;
+		case WSP::EAcceptEncodingDep:
+		case WSP::EAcceptEncoding:
+			{
+			if (wspVersion < CWspHeaderCodec::EVersion1_3)
+				name = 0x02;		// Version 1.1 of Accept-Encoding is encoded as 0x02
+			else
+				name = 0x3C;		// The current version (1.3) of Accept-Encoding is encoded as 0x3C
+			} break;
+		case WSP::ECacheControlDep:
+		case WSP::ECacheControlDep2:
+		case WSP::ECacheControl:
+			{
+			if (wspVersion < CWspHeaderCodec::EVersion1_3)
+				name = 0x08;		// Version 1.1 of Cache-Control is encoded as 0x08
+			else if (wspVersion == CWspHeaderCodec::EVersion1_3)
+				name = 0x3D;		// Version 1.3 of Cache-Control is encoded as 0x3D
+			else
+				name = 0x47;		// The current version (1.4) of Cache-Control is encoded as 0x47
+			} break;
+		case WSP::EContentRangeDep:
+		case WSP::EContentRange:
+			{
+			if (wspVersion < CWspHeaderCodec::EVersion1_3)
+				name = 0x10;		// Version 1.1 of Content-Range is encoded as 0x10
+			else
+				name = 0x3E;		// The current version (1.3) of Content-Range is encoded as 0x3E
+			} break;
+		case WSP::EContentDispositionDep:
+		case WSP::EContentDisposition:
+			{
+			if (wspVersion < CWspHeaderCodec::EVersion1_4)
+				name = 0x2E;		// Version 1.1 of Content-Disposition is encoded as 0x2E
+			else
+				name = 0x45;		// The current version (1.4) of Content-Disposition is encoded as 0x45
+			} break;
+		case WSP::EProfileWarningDep:
+		case WSP::EProfileWarning:
+			{
+			if (wspVersion < CWspHeaderCodec::EVersion1_4)
+				name = 0x37;		// Version 1.2 of Profile-Warning is encoded as 0x37
+			else
+				name = 0x44;		// The current version (1.4) of Profile-Warning is encoded as 0x44
+			} break;
+		default:
+			// Use default return name of fieldName.
+			break;
+		}
+	return name;
+	}
+
+TInt CWspHeaderWriter::EncodeHeaderNameL(RHeaderField& aHeader) const
+	{
+	TInt headerLength = 0;
+	TInt headerNameVal = EncodeFieldName(aHeader.Name());
+	if (headerNameVal == KErrNotFound)
+		{
+		User::LeaveIfError(CheckTokenText(aHeader.Name()));
+		headerLength = aHeader.Name().DesC().Length();
+		}
+	return ++headerLength;
+	}
+
+TInt CWspHeaderWriter::CheckTokenText(RStringF aTokenText) const
+	{
+	const TUint8 KMinValidCharValue = 32;				// Minimum ASCII value for a valid character
+	const TUint8 KMaxValidCharValue = 126;				// Maximum ASCII value for a valid character
+	_LIT8(KTxtSeparators, "()<>@,;:\\\"/[]?={} ");		// Separator characters as defined in RFC2616
+	
+	// Go through each character in the string ensuring that it is within the acceptable ASCII range
+	// and then check that the string does not contain any seperator characters.
+	const TInt tokenTextLength = aTokenText.DesC().Length();
+	for	(TInt ii = 0; ii < tokenTextLength; ++ii)
+		{
+		TUint8 currentChar = aTokenText.DesC()[ii];
+		if ((currentChar < KMinValidCharValue) && (currentChar > KMaxValidCharValue))
+			return KErrCorrupt;
+		if (KTxtSeparators().Locate(currentChar) != KErrNotFound)
+			return KErrCorrupt;
+		}
+	return KErrNone;
+	}
+
+TInt CWspHeaderWriter::CheckTextString(RStringF aTextString) const
+	{
+	const TUint KHorizTab = 9;
+	const TUint KLinefeed = 10;
+	const TUint KCarriageReturn = 13;
+	const TUint KSpace = 32;
+	const TInt textStringLength = aTextString.DesC().Length();
+	for	(TInt ii = 0; ii < textStringLength; ++ii)
+		{
+		TUint8 currentChar = aTextString.DesC()[ii];
+		// Check for an ASCII control character (octets 0-31) or
+		// an ASCII space character (octet 32), but allow ASCII linear white spce (octets 9,
+		// 10, 13 and 32)
+		if (currentChar < 33 && !(currentChar == KHorizTab || currentChar == KLinefeed 
+			|| currentChar == KCarriageReturn || currentChar == KSpace))
+			{
+			return KErrCorrupt;
+			}
+		// Check for an ASCII delete character (octet 127)
+		if (currentChar == 127)
+			return KErrCorrupt;
+		}
+	return KErrNone;
+	}
+
+TInt CWspHeaderWriter::EncodeContentTypeValue(THTTPHdrVal& aContentType) const
+	{
+	TInt encodedToken = aContentType.StrF().Index(WSPContentTypes::Table);
+	if( encodedToken > KErrNotFound )
+		{
+		// Apply some WSP version control on encoded token
+		switch (iCodec.GetWspVersion())
+			{
+			case CWspHeaderCodec::EVersion1_1:
+				{
+				if( encodedToken > 0x2D ) // Highest content-type encoding is 0x2D in v1.1
+					encodedToken = KErrNotFound;
+				} break;
+			case CWspHeaderCodec::EVersion1_2:
+				{
+				if( encodedToken > 0x34 ) // Highest content-type encoding is 0x34 in v1.2
+					encodedToken = KErrNotFound;
+				} break;
+			case CWspHeaderCodec::EVersion1_3:
+				{
+				if( encodedToken > 0x36 ) // Highest content-type encoding is 0x36 in v1.3
+					encodedToken = KErrNotFound;
+				} break;
+			default: // version is 1.4 that can encode all content-types in string table
+				break;
+			}
+		}
+	return encodedToken;
+	}
+
+TInt CWspHeaderWriter::EncodeParameterTokenValue(RStringF aParameterName) const
+	{
+	TInt encodedToken = aParameterName.Index(WSPParam::Table);
+	if( encodedToken > KErrNotFound )
+		{
+		// Apply some WSP version control on encoded token
+		switch (iCodec.GetWspVersion())
+			{
+			// Check for maximum encoding token for current WSP version
+			case CWspHeaderCodec::EVersion1_1:
+				{
+				if( encodedToken > 0x08 ) // Highest parameter token encoding is 0x08 in v1.1
+					encodedToken = KErrNotFound;
+				} break;
+			case CWspHeaderCodec::EVersion1_2:
+				{
+				if( encodedToken > 0x0B ) // Highest parameter token encoding is 0x0b in v1.2
+					encodedToken = KErrNotFound;
+				} break;
+			case CWspHeaderCodec::EVersion1_3:
+				{
+				if( encodedToken > 0x10 ) // Highest parameter token encoding is 0x10 in v1.3
+					encodedToken = KErrNotFound;
+				} break;
+			default: // version is 1.4 that can encode all parameter tokens in string table
+				break;
+			}
+		}
+	return encodedToken;
+	}
+
+// Implementation of CWspDefaultHdrWriter
+//-------------------------------------------------------------------------------
+
+CWspDefaultHdrWriter* CWspDefaultHdrWriter::NewL(RStringPool aStrPool)
+	{
+	return new(ELeave)CWspDefaultHdrWriter(aStrPool);
+	}
+
+CWspDefaultHdrWriter* CWspDefaultHdrWriter::NewLC(RStringPool aStrPool)
+	{
+	CWspDefaultHdrWriter* self = CWspDefaultHdrWriter::NewL(aStrPool);
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+CWspDefaultHdrWriter::CWspDefaultHdrWriter(RStringPool aStrPool)
+	: iStrPool(aStrPool)
+	{
+	}
+
+CWspDefaultHdrWriter::~CWspDefaultHdrWriter()
+	{
+	}
+
+void CWspDefaultHdrWriter::EncodeHeaderL(RHeaderField& aHeader)
+	{
+	THeaderFieldPartIter partIter = aHeader.PartsL();
+	CWspHeaderEncoder* encoder = CWspHeaderEncoder::NewL();
+	CleanupStack::PushL(encoder);
+	TInt partCount = 0;
+	aHeader.BeginRawDataL();
+	partIter.First();
+	// Loop through all the parts and build up the raw data
+	while (!partIter.AtEnd())
+		{
+		encoder->StartHeaderL(aHeader.Name().DesC());
+		const CHeaderFieldPart* part = partIter();
+		if (part != NULL)
+			{
+			++partCount;
+			THTTPHdrVal value = part->Value();
+			if (value.Type() == THTTPHdrVal::KStrFVal)
+				encoder->AddTextStringL(value.StrF().DesC());
+			else
+				User::Leave(KErrCorrupt);
+			}
+
+		HBufC8* buffer = encoder->EndHeaderL();
+		CleanupStack::PushL(buffer);
+		TInt startPos = 0;
+		// If this is the first part then don't include the header name
+		if (partCount == 1)
+			startPos = (aHeader.Name().DesC().Length()) + 1;
+		TPtrC8 data(buffer->Mid(startPos));
+		aHeader.WriteRawDataL(data);
+		CleanupStack::PopAndDestroy(buffer);
+		++partIter;
+		}
+	aHeader.CommitRawData();
+	CleanupStack::PopAndDestroy(encoder);
+	}