applayerpluginsandutils/httpprotocolplugins/wspheadercodec/CWspHeaderReader.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 "cwspheaderreader.h"
       
    29 
       
    30 // Constants
       
    31 const TInt KMaxNumQDigits = 5;	// Maximum number of digits for a 'Q' value
       
    32 const TUint32 KRegisteredContentTypesOffset = 0x0201; // Registered content types offset
       
    33 const TUint8 KTopBitMask = 0x80; // Bit-wise mask for setting top bit to 1
       
    34 
       
    35 CWspHeaderReader::~CWspHeaderReader()
       
    36 	{
       
    37 	}
       
    38 
       
    39 CWspHeaderReader* CWspHeaderReader::NewL(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
       
    40 	{
       
    41 	return new(ELeave)CWspHeaderReader(aStrPool, aStrTable, aCodec);
       
    42 	}
       
    43 
       
    44 CWspHeaderReader* CWspHeaderReader::NewLC(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
       
    45 	{
       
    46 	CWspHeaderReader* self = CWspHeaderReader::NewL(aStrPool, aStrTable, aCodec);
       
    47 	CleanupStack::PushL(self);
       
    48 	return self;
       
    49 	}
       
    50 
       
    51 CWspHeaderReader::CWspHeaderReader(RStringPool aStrPool, const TStringTable& aStrTable, CWspHeaderCodec& aCodec)
       
    52 	: iStrPool(aStrPool), iStrTable(aStrTable), iCodec(aCodec)
       
    53 	{
       
    54 	}
       
    55 
       
    56 void CWspHeaderReader::DecodeHeaderL(RHeaderField& aHeader)
       
    57 	{
       
    58 	switch( aHeader.Name().Index(iStrTable) )
       
    59 		{
       
    60 		case WSP::EContentType:
       
    61 			DecodeContentTypeL(aHeader);
       
    62 			break;
       
    63 		case WSP::EDate:
       
    64 		case WSP::ELastModified:
       
    65 			DecodeGenericDateValueL(aHeader);
       
    66 			break;
       
    67 		case WSP::EContentLocation:
       
    68 		case WSP::ELocation:
       
    69 		case WSP::EServer:
       
    70 		case WSP::EVia:
       
    71 		case WSP::EXWapInitiatorURI:
       
    72 		case WSP::EUpgrade:
       
    73 			DecodeGenericNewStringValueL(aHeader);
       
    74 			break;
       
    75 		case WSP::EPragma:
       
    76 			DecodePragmaL(aHeader);
       
    77 			break;
       
    78 		case WSP::EVary:
       
    79 		case WSP::ETrailer:
       
    80 			DecodeGenericFieldNameL(aHeader);
       
    81 			break;
       
    82 		case WSP::EWWWAuthenticate:
       
    83 		case WSP::EProxyAuthenticate:
       
    84 			DecodeGenericChallengeL(aHeader);
       
    85 			break;
       
    86 		case WSP::ESetCookie:
       
    87 			DecodeSetCookieL(aHeader);
       
    88 			break;
       
    89 		case WSP::EEncodingVersion:
       
    90 			DecodeEncodingVersionL(aHeader);
       
    91 			break;
       
    92 		case WSP::EAcceptRanges:
       
    93 			DecodeAcceptRangesL(aHeader);
       
    94 			break;
       
    95 		case WSP::EContentEncoding:
       
    96 			DecodeContentEncodingL(aHeader);
       
    97 			break;
       
    98 		case WSP::EContentLanguage:
       
    99 			DecodeContentLanguageL(aHeader);
       
   100 			break;
       
   101 		case WSP::EContentMD5:
       
   102 			DecodeContentMD5L(aHeader);
       
   103 			break;
       
   104 		case WSP::ERetryAfter:
       
   105 			DecodeRetryAfterL(aHeader);
       
   106 			break;
       
   107 		case WSP::EContentRange:
       
   108 		case WSP::EContentRangeDep:
       
   109 			DecodeContentRangeL(aHeader);
       
   110 			break;
       
   111 		case WSP::EXWapApplicationId:
       
   112 			DecodeXWapApplicationIdL(aHeader);
       
   113 			break;
       
   114 		case WSP::EPushFlag:
       
   115 			DecodePushFlagL(aHeader);
       
   116 			break;
       
   117 		case WSP::EAllow:
       
   118 			DecodeAllowL(aHeader);
       
   119 			break;
       
   120 		case WSP::EWarning:
       
   121 			DecodeWarningL(aHeader);
       
   122 			break;
       
   123 		case WSP::EProfileWarning:
       
   124 		case WSP::EProfileWarningDep:
       
   125 			DecodeProfileWarningL(aHeader);
       
   126 			break;
       
   127 		default:
       
   128 			User::Leave(KErrNotSupported);
       
   129 			break;
       
   130 		}
       
   131 	}
       
   132 
       
   133 
       
   134 void CWspHeaderReader::DecodeContentTypeL(RHeaderField& aHeader) const
       
   135 	{
       
   136 	TPtrC8 rawData;
       
   137 	aHeader.RawDataL(rawData);
       
   138 	CheckLengthL(rawData, 1);
       
   139 
       
   140 	if( !(CheckNullDesPartL(aHeader, rawData, 0)) )
       
   141 		{
       
   142 		TWspPrimitiveDecoder wspDecoder(rawData);
       
   143 		switch( wspDecoder.VarType() )
       
   144 			{
       
   145 			case TWspPrimitiveDecoder::E7BitVal:
       
   146 				{
       
   147 				TUint8 contentTypeToken = 0;
       
   148 				User::LeaveIfError(wspDecoder.Val7Bit(contentTypeToken));
       
   149 				RStringF contentType = iStrPool.StringF(contentTypeToken, WSPContentTypes::Table);
       
   150 				SetFStringPartL(aHeader, 0, contentType);
       
   151 				} break;
       
   152 			case TWspPrimitiveDecoder::EString:
       
   153 				{
       
   154 				AddNewDecoderStringPartL(aHeader, wspDecoder);
       
   155 				} break;
       
   156 			case TWspPrimitiveDecoder::ELengthVal:
       
   157 				{
       
   158 				TInt dataLength = 0;
       
   159 				TInt err = wspDecoder.LengthVal(dataLength);
       
   160 				User::LeaveIfError(err);
       
   161 				TInt bytesProcessed = err;
       
   162 				TWspPrimitiveDecoder::TWspHeaderType type = wspDecoder.VarType();
       
   163 				CHeaderFieldPart* fieldPart = NULL;
       
   164 				if( type == TWspPrimitiveDecoder::E7BitVal || type == TWspPrimitiveDecoder::ELengthVal )
       
   165 					{
       
   166 					TUint32 contentTypeToken = 0;
       
   167 					err = wspDecoder.Integer(contentTypeToken);
       
   168 					User::LeaveIfError(err);
       
   169 					bytesProcessed += err;
       
   170 					RStringF contentTypeStr;
       
   171 					if( contentTypeToken < KRegisteredContentTypesOffset )
       
   172 						contentTypeStr = iStrPool.StringF(contentTypeToken, WSPContentTypes::Table);
       
   173 					else
       
   174 						contentTypeStr = iStrPool.StringF((contentTypeToken-KRegisteredContentTypesOffset), WSPRegContentTypes::Table);
       
   175 					
       
   176 					fieldPart = &(SetFStringPartL(aHeader, 0, contentTypeStr));
       
   177 					}
       
   178 				else if( type == TWspPrimitiveDecoder::EString )
       
   179 					{
       
   180 					TPtrC8 contentType;
       
   181 					err = wspDecoder.String(contentType);
       
   182 					User::LeaveIfError(err);
       
   183 					bytesProcessed += err;
       
   184 					fieldPart = &(SetNewFStringPartL(aHeader, 0, contentType));
       
   185 					}
       
   186 				else
       
   187 					User::Leave(KErrCorrupt);
       
   188 
       
   189 				// Check if paramters exist
       
   190 				while( bytesProcessed < rawData.Length() )
       
   191 					{
       
   192 					TPtrC8 parameterBlock(rawData.Mid(bytesProcessed));
       
   193 					bytesProcessed += DecodeGenericSingleParameterL(parameterBlock, *fieldPart);
       
   194 					}
       
   195 				} break;
       
   196 			default:
       
   197 				User::Leave(KErrCorrupt);
       
   198 			}
       
   199 		}
       
   200 	}
       
   201 
       
   202 void CWspHeaderReader::DecodePragmaL(RHeaderField& aHeader) const
       
   203 	{
       
   204 	TPtrC8 rawData;
       
   205 	aHeader.RawDataL(rawData);
       
   206 	CheckLengthL(rawData, 1);
       
   207 
       
   208 	// Check for <Octet 128> which indicates "No-Cache" string
       
   209 	if( rawData[0] == 128 )
       
   210 		{
       
   211 		SetFStringPartL(aHeader, 0, iStrPool.StringF(WSPStdConstants::ENoCache, WSPStdConstants::Table));
       
   212 		}
       
   213 	else
       
   214 		{
       
   215 		TWspPrimitiveDecoder wspDecoder(rawData);
       
   216 		if( wspDecoder.VarType() == TWspPrimitiveDecoder::ELengthVal )
       
   217 			{
       
   218 			TInt dataLength = 0;
       
   219 			TInt bytesProcessed = wspDecoder.LengthVal(dataLength);
       
   220 			User::LeaveIfError(bytesProcessed);
       
   221 			TPtrC8 rawParamBlock(rawData.Mid(bytesProcessed));
       
   222 			// Check that there is only one parameter block
       
   223 			if( dataLength != rawParamBlock.Length() )
       
   224 				User::Leave(KErrCorrupt);
       
   225 			CHeaderFieldPart& fieldPart = SetNewFStringPartL(aHeader, 0, KNullDesC8());
       
   226 			bytesProcessed += DecodeGenericSingleParameterL(rawParamBlock, fieldPart);
       
   227 			if( bytesProcessed != rawData.Length() )
       
   228 				User::Leave(KErrCorrupt);
       
   229 			}
       
   230 		}
       
   231 	}
       
   232 
       
   233 void CWspHeaderReader::DecodeSetCookieL(RHeaderField& aHeader) const
       
   234 	{
       
   235 	TPtrC8 rawData;
       
   236 	aHeader.RawDataL(rawData);
       
   237 	CheckLengthL(rawData, 2);
       
   238 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   239 	if( wspDecoder.VarType() != TWspPrimitiveDecoder::ELengthVal )
       
   240 		User::Leave(KErrCorrupt);
       
   241 	TInt valueLength = 0;
       
   242 	TInt bytesProcessed = wspDecoder.LengthVal(valueLength);
       
   243 	User::LeaveIfError(bytesProcessed);
       
   244 
       
   245 	// Get the first part which is the cookie-version
       
   246 	TInt err = 0;
       
   247 	if( CheckForNullStringL(rawData, bytesProcessed, wspDecoder) )
       
   248 		{
       
   249 		SetNewFStringPartL(aHeader, 0, KNullDesC8());
       
   250 		}
       
   251 	else
       
   252 		{
       
   253 		RStringF version;
       
   254 		err = wspDecoder.VersionL(iStrPool, version);
       
   255 		User::LeaveIfError(err);
       
   256 		bytesProcessed += err;
       
   257 		CleanupClosePushL(version);
       
   258 		SetFStringPartL(aHeader, 0, version);
       
   259 		CleanupStack::PopAndDestroy(&version);
       
   260 		}
       
   261 
       
   262 	// Loop through the next two 
       
   263 	// Get the second part which is the cookie-name
       
   264 	// Get the third part which is the cookie-value
       
   265 	CHeaderFieldPart* fieldPart = NULL;
       
   266 	for(TInt ii=1; ii<3; ++ii)
       
   267 		{
       
   268 		TPtrC8 cookiePart(KNullDesC8());
       
   269 		if( !(CheckForNullStringL(rawData, bytesProcessed, wspDecoder)) )
       
   270 			{
       
   271 			err = wspDecoder.String(cookiePart);
       
   272 			User::LeaveIfError(err);
       
   273 			bytesProcessed += err;
       
   274 			}
       
   275 		fieldPart = &(SetNewFStringPartL(aHeader, ii, cookiePart));
       
   276 		}
       
   277 
       
   278 	// Check if there are any parameters. if so add them to the 3rd part
       
   279 	if( fieldPart != NULL ) 
       
   280 		{
       
   281 		while( bytesProcessed < rawData.Length() )
       
   282 			{
       
   283 			TPtrC8 parameterBlock(rawData.Mid(bytesProcessed));
       
   284 			bytesProcessed += DecodeGenericSingleParameterL(parameterBlock, *fieldPart);
       
   285 			}
       
   286 		}
       
   287 	}
       
   288 
       
   289 TBool CWspHeaderReader::CheckForNullStringL(TPtrC8& aRawData, TInt& aBytesRead,
       
   290 											TWspPrimitiveDecoder& aDecoder) const
       
   291 	{
       
   292 	// Check that the buffer is not out of range
       
   293 	if( aBytesRead >= aRawData.Length() )
       
   294 		User::Leave(KErrCorrupt);
       
   295 
       
   296 	// Check if the data at the indicated position is a NULL terminator
       
   297 	if( aRawData[aBytesRead] == 0 )
       
   298 		{
       
   299 		TUint8 value = 0;
       
   300 		TInt err = aDecoder.Val7Bit(value);
       
   301 		User::LeaveIfError(err);
       
   302 		aBytesRead += err;
       
   303 		return ETrue;
       
   304 		}
       
   305 	return EFalse;
       
   306 	}
       
   307 
       
   308 void CWspHeaderReader::DecodeEncodingVersionL(RHeaderField& aHeader) const
       
   309 	{
       
   310 	TPtrC8 rawData;
       
   311 	aHeader.RawDataL(rawData);
       
   312 	CheckLengthL(rawData, 1);
       
   313 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   314 	
       
   315 	if( !(CheckNullDesPartL(aHeader, rawData, 0)) )
       
   316 		{
       
   317 		// Check type and decode accordingly
       
   318 		switch( wspDecoder.VarType() )
       
   319 			{
       
   320 			case TWspPrimitiveDecoder::ELengthVal:
       
   321 				{
       
   322 				TInt valLength = 0;
       
   323 				TInt bytesRead = 0;
       
   324 				TInt err = wspDecoder.LengthVal(valLength);
       
   325 				User::LeaveIfError(err);
       
   326 				bytesRead += err;
       
   327 				if( wspDecoder.VarType() == TWspPrimitiveDecoder::E7BitVal )
       
   328 					{
       
   329 					TUint8 codePage = 0;
       
   330 					err = wspDecoder.Val7Bit(codePage);
       
   331 					User::LeaveIfError(err);
       
   332 					bytesRead += err;
       
   333 					SetNewIntegerPartL(aHeader, 0, codePage);
       
   334 					if( bytesRead < rawData.Length() )
       
   335 						{
       
   336 						// Check for Null string first
       
   337 						if( rawData[bytesRead] == 0 )
       
   338 							SetNewFStringPartL(aHeader, 1, KNullDesC8());
       
   339 						else
       
   340 							DecodeGenericVersionL(aHeader, wspDecoder, 1);
       
   341 						}
       
   342 					}
       
   343 				else
       
   344 					User::Leave(KErrCorrupt);
       
   345 				} break;
       
   346 			case TWspPrimitiveDecoder::EString:
       
   347 			case TWspPrimitiveDecoder::E7BitVal:
       
   348 				{
       
   349 				DecodeGenericVersionL(aHeader, wspDecoder, 0);
       
   350 				} break;
       
   351 			default:
       
   352 				User::Leave(KErrCorrupt);
       
   353 				break;
       
   354 			}
       
   355 		}
       
   356 	}
       
   357 
       
   358 void CWspHeaderReader::DecodeGenericVersionL(RHeaderField& aHeader, TWspPrimitiveDecoder& aDecoder, TInt aIndex) const
       
   359 	{
       
   360 	RStringF versionValue;
       
   361 	CleanupClosePushL(versionValue);
       
   362 	User::LeaveIfError(aDecoder.VersionL(iStrPool, versionValue));
       
   363 	SetFStringPartL(aHeader, aIndex, versionValue);
       
   364 	CleanupStack::PopAndDestroy(&versionValue);
       
   365 	}
       
   366 
       
   367 void CWspHeaderReader::DecodeAcceptRangesL(RHeaderField& aHeader) const
       
   368 	{
       
   369 	TPtrC8 rawData;
       
   370 	aHeader.RawDataL(rawData);
       
   371 	CheckLengthL(rawData, 1);
       
   372 	TInt acceptRangeIndex = KErrNotFound;
       
   373 	switch( rawData[0] )
       
   374 		{
       
   375 		case 128: // This is the token for 'None'
       
   376 			{
       
   377 			acceptRangeIndex = WSPStdConstants::ENone;
       
   378 			} break;
       
   379 		case 129: // This is the token for 'Bytes'
       
   380 			{
       
   381 			acceptRangeIndex = WSPStdConstants::EBytes;
       
   382 			} break;
       
   383 		default: // Must be token text
       
   384 			{
       
   385 			TWspPrimitiveDecoder wspDecoder(rawData);
       
   386 			// Check that the data is of string type
       
   387 			if( wspDecoder.VarType() == TWspPrimitiveDecoder::EString )
       
   388 				{
       
   389 				// Extract and add the string as a part
       
   390 				AddNewDecoderStringPartL(aHeader, wspDecoder);
       
   391 				}
       
   392 			else
       
   393 				User::Leave(KErrCorrupt);
       
   394 			} break;
       
   395 		}
       
   396 
       
   397 	if(acceptRangeIndex!=KErrNotFound)
       
   398 		SetFStringPartL(aHeader, 0, iStrPool.StringF(acceptRangeIndex, WSPStdConstants::Table));
       
   399 	}
       
   400 
       
   401 void CWspHeaderReader::DecodeContentEncodingL(RHeaderField& aHeader) const
       
   402 	{
       
   403 	TPtrC8 rawHeaderData;
       
   404 	aHeader.RawDataL(rawHeaderData);
       
   405 	TInt startPos = 0;
       
   406 	TInt separatorPos = 0;
       
   407 	TInt ii = 0;
       
   408 	// Loop through all the parts separated by the header field token name
       
   409 	do
       
   410 		{
       
   411 		TPtrC8 rawData(rawHeaderData.Mid(startPos));
       
   412 		separatorPos = rawData.Locate((TUint8)(WSP::EContentEncoding + KTopBitMask));
       
   413 		if(separatorPos!=KErrNotFound)
       
   414 			rawData.Set(rawHeaderData.Mid(startPos, separatorPos));
       
   415 
       
   416 		CheckLengthL(rawData, 1);
       
   417 		TInt contentEncodingIndex = KErrNotFound;
       
   418 		switch( rawData[0] )
       
   419 			{
       
   420 			case 128: // This is the token for 'GZip'
       
   421 				{
       
   422 				contentEncodingIndex = WSPStdConstants::EGzip;
       
   423 				} break;
       
   424 			case 129: // This is the token for 'Compress'
       
   425 				{
       
   426 				contentEncodingIndex = WSPStdConstants::ECompress;
       
   427 				} break;
       
   428 			case 130: // This is the token for 'Deflate'
       
   429 				{
       
   430 				contentEncodingIndex = WSPStdConstants::EDeflate;
       
   431 				} break;
       
   432 			default: // Must be token text
       
   433 				{
       
   434 				TWspPrimitiveDecoder wspDecoder(rawData);
       
   435 				// Check that the data is of string type
       
   436 				if( wspDecoder.VarType() == TWspPrimitiveDecoder::EString )
       
   437 					{
       
   438 					// Extract and add the string as a part
       
   439 					AddNewDecoderStringPartL(aHeader, wspDecoder, ii);
       
   440 					}
       
   441 				else
       
   442 					User::Leave(KErrCorrupt);
       
   443 				} break;
       
   444 			}
       
   445 
       
   446 		if(contentEncodingIndex!=KErrNotFound)
       
   447 			SetFStringPartL(aHeader, ii, iStrPool.StringF(contentEncodingIndex, WSPStdConstants::Table));
       
   448 		++ii;
       
   449 		startPos += (separatorPos + 1);
       
   450 		} while( separatorPos != KErrNotFound );
       
   451 	}
       
   452 
       
   453 void CWspHeaderReader::DecodeContentLanguageL(RHeaderField& aHeader) const
       
   454 	{
       
   455 	TPtrC8 rawHeaderData;
       
   456 	aHeader.RawDataL(rawHeaderData);
       
   457 	TInt startPos = 0;
       
   458 	TInt separatorPos = 0;
       
   459 	TInt ii = 0;
       
   460 	// Loop through all the parts separated by the header field name
       
   461 	do
       
   462 		{
       
   463 		TPtrC8 rawData(rawHeaderData.Mid(startPos));
       
   464 		separatorPos = rawData.Locate((TUint8)(WSP::EContentLanguage + KTopBitMask));
       
   465 		if(separatorPos!=KErrNotFound)
       
   466 			rawData.Set(rawHeaderData.Mid(startPos, separatorPos));
       
   467 
       
   468 		CheckLengthL(rawData, 1);
       
   469 		// First check for any language ('*') encoded as octet 128
       
   470 		if( rawData[0] == 128 )
       
   471 			SetFStringPartL(aHeader, ii, iStrPool.StringF(WSPLanguages::EAnyLanguage, WSPLanguages::Table));
       
   472 		else
       
   473 			{
       
   474 			// Otherwise the language is encoded as a short int, long int or token text
       
   475 			TWspPrimitiveDecoder wspDecoder(rawData);
       
   476 			switch( wspDecoder.VarType() )
       
   477 				{
       
   478 				case TWspPrimitiveDecoder::E7BitVal: // short int
       
   479 				case TWspPrimitiveDecoder::ELengthVal: // long int
       
   480 					{
       
   481 					TUint32 languageToken = 0;
       
   482 					User::LeaveIfError(wspDecoder.Integer(languageToken));
       
   483 					// Check if the language token is short or long int as long requires an offset
       
   484 					if( languageToken >= 128 )
       
   485 						// Language token is long int so apply the offset
       
   486 						--languageToken;
       
   487 					SetFStringPartL(aHeader, ii, iStrPool.StringF(languageToken, WSPLanguages::Table));
       
   488 					} break;
       
   489 				case TWspPrimitiveDecoder::EString: // token text
       
   490 					{
       
   491 					// Extract the token text and set the part
       
   492 					AddNewDecoderStringPartL(aHeader, wspDecoder, ii);
       
   493 					} break;
       
   494 				default:
       
   495 					User::Leave(KErrCorrupt);
       
   496 					break;
       
   497 				}
       
   498 			}
       
   499 
       
   500 		++ii;
       
   501 		startPos += (separatorPos + 1);
       
   502 		} while( separatorPos != KErrNotFound );
       
   503 	}
       
   504 
       
   505 void CWspHeaderReader::DecodeContentMD5L(RHeaderField& aHeader) const
       
   506 	{
       
   507 	TPtrC8 rawData;
       
   508 	aHeader.RawDataL(rawData);
       
   509 	CheckLengthL(rawData, 1);
       
   510 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   511 	if( wspDecoder.VarType() == TWspPrimitiveDecoder::ELengthVal )
       
   512 		{
       
   513 		TInt length = 0;
       
   514 		TInt bytesRead = wspDecoder.LengthVal(length);
       
   515 		User::LeaveIfError(bytesRead);
       
   516 		TPtrC8 md5Data(rawData.Mid(bytesRead));
       
   517 		if( md5Data.Length() != length )
       
   518 			User::Leave(KErrCorrupt);
       
   519 
       
   520 		SetNewStringPartL(aHeader, 0, md5Data);
       
   521 		}
       
   522 	else
       
   523 		User::Leave(KErrCorrupt);
       
   524 	}
       
   525 
       
   526 void CWspHeaderReader::DecodeRetryAfterL(RHeaderField& aHeader) const
       
   527 	{
       
   528 	TPtrC8 rawData;
       
   529 	aHeader.RawDataL(rawData);
       
   530 	CheckLengthL(rawData, 1);
       
   531 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   532 	if( wspDecoder.VarType() == TWspPrimitiveDecoder::ELengthVal )
       
   533 		{
       
   534 		TInt lengthVal = 0;
       
   535 		TInt bytesRead = wspDecoder.LengthVal(lengthVal);
       
   536 		User::LeaveIfError(bytesRead);
       
   537 		switch( rawData[bytesRead] )
       
   538 			{
       
   539 			case 128: // This is an absolute time
       
   540 				{
       
   541 				TUint8 updateOffset = 0;
       
   542 				User::LeaveIfError(wspDecoder.Val7Bit(updateOffset));
       
   543 				TDateTime dateTime(1970, EJanuary, 0, 0, 0, 0, 0);
       
   544 				User::LeaveIfError(wspDecoder.Date(dateTime));
       
   545 				SetNewDatePartL(aHeader, 0, dateTime);
       
   546 				} break;
       
   547 			case 129: // This is a relative time
       
   548 				{
       
   549 				TUint8 updateOffset = 0;
       
   550 				User::LeaveIfError(wspDecoder.Val7Bit(updateOffset));
       
   551 				TUint32 relativeTime = 0;
       
   552 				User::LeaveIfError(wspDecoder.Integer(relativeTime));
       
   553 				SetNewIntegerPartL(aHeader, 0, relativeTime);
       
   554 				} break;
       
   555 			default:
       
   556 				User::Leave(KErrCorrupt);
       
   557 				break;
       
   558 			}
       
   559 		}
       
   560 	else
       
   561 		User::Leave(KErrCorrupt);
       
   562 	}
       
   563 
       
   564 void CWspHeaderReader::DecodeContentRangeL(RHeaderField& aHeader) const
       
   565 	{
       
   566 	TPtrC8 rawData;
       
   567 	aHeader.RawDataL(rawData);
       
   568 	CheckLengthL(rawData, 1);
       
   569 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   570 	if( wspDecoder.VarType() == TWspPrimitiveDecoder::ELengthVal )
       
   571 		{
       
   572 		TInt lengthVal = 0;
       
   573 		TInt bytesRead = wspDecoder.LengthVal(lengthVal);
       
   574 		User::LeaveIfError(bytesRead);
       
   575 		
       
   576 		// Get the first part, first byte pos
       
   577 		TUint32 uintvarValue = 0;
       
   578 		TInt err = wspDecoder.UintVar(uintvarValue);
       
   579 		User::LeaveIfError(err);
       
   580 		bytesRead += err;
       
   581 		SetNewIntegerPartL(aHeader, 0, uintvarValue);
       
   582 
       
   583 		// Get the second part, entity length
       
   584 		// Check for '*' token <octet 128> and the encoding version is greater than v1.2
       
   585 		if( (rawData[bytesRead]) == 128 && (iCodec.GetWspVersion() > CWspHeaderCodec::EVersion1_2) )
       
   586 			{
       
   587 			RStringF unknownLenStr = iStrPool.StringF(WSPStdConstants::EAny, WSPStdConstants::Table);
       
   588 			SetFStringPartL(aHeader, 1, unknownLenStr);
       
   589 			}
       
   590 		else
       
   591 			{
       
   592 			User::LeaveIfError(wspDecoder.UintVar(uintvarValue));
       
   593 			SetNewIntegerPartL(aHeader, 1, uintvarValue);
       
   594 			}
       
   595 		}
       
   596 	else
       
   597 		User::Leave(KErrCorrupt);
       
   598 	}
       
   599 
       
   600 void CWspHeaderReader::DecodeXWapApplicationIdL(RHeaderField& aHeader) const
       
   601 	{
       
   602 	TPtrC8 rawData;
       
   603 	aHeader.RawDataL(rawData);
       
   604 	CheckLengthL(rawData, 1);
       
   605 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   606 	switch( wspDecoder.VarType() )
       
   607 			{
       
   608 			case TWspPrimitiveDecoder::E7BitVal:
       
   609 			case TWspPrimitiveDecoder::ELengthVal:
       
   610 				{
       
   611 				if( rawData[0] != 0 )
       
   612 					{
       
   613 					TUint32 applicationID = 0;
       
   614 					User::LeaveIfError(wspDecoder.Integer(applicationID));
       
   615 					SetNewIntegerPartL(aHeader, 0, applicationID);
       
   616 					}
       
   617 				} break;
       
   618 			default:
       
   619 				DecodeGenericNewStringValueL(aHeader);
       
   620 				break;
       
   621 			}
       
   622 	}
       
   623 
       
   624 void CWspHeaderReader::DecodePushFlagL(RHeaderField& aHeader) const
       
   625 	{
       
   626 	TPtrC8 rawData;
       
   627 	aHeader.RawDataL(rawData);
       
   628 	CheckLengthL(rawData, 1);
       
   629 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   630 	// Check that the value is a short integer
       
   631 	if( wspDecoder.VarType() == TWspPrimitiveDecoder::E7BitVal )
       
   632 		{
       
   633 		TUint8 pushFlagVal = 0;
       
   634 		User::LeaveIfError(wspDecoder.Val7Bit(pushFlagVal));
       
   635 		SetNewIntegerPartL(aHeader, 0, pushFlagVal);
       
   636 		}
       
   637 	else
       
   638 		User::Leave(KErrCorrupt);
       
   639 	}
       
   640 
       
   641 void CWspHeaderReader::DecodeAllowL(RHeaderField& aHeader) const
       
   642 	{
       
   643 	TPtrC8 rawHeaderData;
       
   644 	aHeader.RawDataL(rawHeaderData);
       
   645 	TInt startPos = 0;
       
   646 	TInt separatorPos = 0;
       
   647 	TInt ii = 0;
       
   648 	// Loop through all the parts separated by the header field name
       
   649 	do
       
   650 		{
       
   651 		TPtrC8 rawData(rawHeaderData.Mid(startPos));
       
   652 		separatorPos = rawData.Locate((TUint8)(WSP::EAllow + KTopBitMask));
       
   653 		if(separatorPos!=KErrNotFound)
       
   654 			rawData.Set(rawHeaderData.Mid(startPos, separatorPos));
       
   655 		
       
   656 		CheckLengthL(rawData, 1);
       
   657 		TWspPrimitiveDecoder wspDecoder(rawData);
       
   658 		// Check that the value is a short integer
       
   659 		if( wspDecoder.VarType() == TWspPrimitiveDecoder::E7BitVal )
       
   660 			{
       
   661 			TUint8 pushFlagVal = 0;
       
   662 			User::LeaveIfError(wspDecoder.Val7Bit(pushFlagVal));
       
   663 			// Get the correct string for the integer value from the WSP Type Constants table
       
   664 			TInt stringTableIndex = KErrNotFound;
       
   665 			switch(pushFlagVal)
       
   666 				{
       
   667 				case 0x40: // Get
       
   668 					stringTableIndex = WSPTypeConstants::EGet;
       
   669 					break;
       
   670 				case 0x41: // Options
       
   671 					stringTableIndex = WSPTypeConstants::EOptions;
       
   672 					break;
       
   673 				case 0x42: // Head
       
   674 					stringTableIndex = WSPTypeConstants::EHead;
       
   675 					break;
       
   676 				case 0x43: // Delete
       
   677 					stringTableIndex = WSPTypeConstants::EDelete;
       
   678 					break;
       
   679 				case 0x44: // Trace
       
   680 					stringTableIndex = WSPTypeConstants::ETrace;
       
   681 					break;
       
   682 				case 0x60: // Post
       
   683 					stringTableIndex = WSPTypeConstants::EPost;
       
   684 					break;
       
   685 				case 0x61: // Put
       
   686 					stringTableIndex = WSPTypeConstants::EPut;
       
   687 					break;
       
   688 				default: // Not found so leave
       
   689 					User::Leave(KErrNotSupported);
       
   690 					break;
       
   691 				}
       
   692 			RStringF allowValue = iStrPool.StringF(stringTableIndex, WSPTypeConstants::Table);
       
   693 			SetFStringPartL(aHeader, ii, allowValue);
       
   694 			}
       
   695 		else
       
   696 			User::Leave(KErrCorrupt);
       
   697 		
       
   698 		++ii;
       
   699 		startPos += (separatorPos + 1);
       
   700 		} while( separatorPos != KErrNotFound );
       
   701 	}
       
   702 
       
   703 void CWspHeaderReader::DecodeWarningL(RHeaderField& aHeader) const
       
   704 	{
       
   705 	TPtrC8 rawData;
       
   706 	aHeader.RawDataL(rawData);
       
   707 	CheckLengthL(rawData, 1);
       
   708 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   709 	switch( wspDecoder.VarType() )
       
   710 		{
       
   711 		case TWspPrimitiveDecoder::E7BitVal: // This is a short int warn code
       
   712 			{
       
   713 			DecodeGenericWarnCodeL(aHeader, wspDecoder);
       
   714 			} break;
       
   715 		case TWspPrimitiveDecoder::ELengthVal: // This is value-length warning value
       
   716 			{
       
   717 			// Get the first part - warn-code (short int)
       
   718 			TInt length = 0;
       
   719 			TInt bytesProcessed = wspDecoder.LengthVal(length);
       
   720 			User::LeaveIfError(bytesProcessed);
       
   721 			DecodeGenericWarnCodeL(aHeader, wspDecoder);
       
   722 			++bytesProcessed;
       
   723 			
       
   724 			// Get the second part - warn-agent (text string)
       
   725 			if(CheckForNullStringL(rawData, bytesProcessed, wspDecoder))
       
   726 				SetNewFStringPartL(aHeader, 1, KNullDesC8());
       
   727 			else
       
   728 				bytesProcessed += AddNewDecoderStringPartL(aHeader, wspDecoder, 1);
       
   729 
       
   730 			// Get the third part - warn-text (text string)
       
   731 			if(CheckForNullStringL(rawData, bytesProcessed, wspDecoder))
       
   732 				SetNewFStringPartL(aHeader, 2, KNullDesC8());
       
   733 			else
       
   734 				{
       
   735 				AddNewDecoderStringPartL(aHeader, wspDecoder, 2);
       
   736 				}
       
   737 			} break;
       
   738 		default:
       
   739 			User::LeaveIfError(KErrCorrupt);
       
   740 			break;
       
   741 		}
       
   742 	}
       
   743 	
       
   744 void CWspHeaderReader::DecodeProfileWarningL(RHeaderField& aHeader) const
       
   745 	{
       
   746 	TPtrC8 rawData;
       
   747 	aHeader.RawDataL(rawData);
       
   748 	CheckLengthL(rawData, 1);
       
   749 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   750 	switch (wspDecoder.VarType())
       
   751 		{
       
   752 		case TWspPrimitiveDecoder::E7BitVal: // This is a short int profile warn-code
       
   753 			{
       
   754 			DecodeGenericWarnCodeL(aHeader, wspDecoder);
       
   755 			} break;
       
   756 		case TWspPrimitiveDecoder::ELengthVal:
       
   757 			{
       
   758 			TInt length = 0;
       
   759 			TInt bytesRead = wspDecoder.LengthVal(length);
       
   760 			User::LeaveIfError(bytesRead);
       
   761 			
       
   762 			// Get the first part - profile warn-code (short int)
       
   763 			DecodeGenericWarnCodeL(aHeader, wspDecoder);
       
   764 			++bytesRead;
       
   765 			
       
   766 			// Get the second part - warn-target
       
   767 			if(CheckForNullStringL(rawData, bytesRead, wspDecoder))
       
   768 				SetNewFStringPartL(aHeader, 1, KNullDesC8());
       
   769 			else
       
   770 				bytesRead += AddNewDecoderStringPartL(aHeader, wspDecoder, 1);
       
   771 
       
   772 			// Get the warn-date if it exists
       
   773 			if( bytesRead < rawData.Length() )
       
   774 				{
       
   775 				TDateTime dateTime(1970, EJanuary, 0, 0, 0, 0, 0);
       
   776 				User::LeaveIfError(wspDecoder.Date(dateTime));
       
   777 				SetNewDatePartL(aHeader, 2, dateTime);
       
   778 				}
       
   779 			} break;
       
   780 		default:
       
   781 			User::Leave(KErrCorrupt);
       
   782 			break;
       
   783 		}
       
   784 	}
       
   785 
       
   786 
       
   787 // Generic encoding methods
       
   788 
       
   789 void CWspHeaderReader::DecodeGenericWarnCodeL(RHeaderField& aHeader, TWspPrimitiveDecoder& aDecoder) const
       
   790 	{
       
   791 	TUint8 warnCode = 0;
       
   792 	User::LeaveIfError(aDecoder.Val7Bit(warnCode));
       
   793 	// Convert the code
       
   794 	TInt convertedCode = 0;
       
   795 	switch( warnCode )
       
   796 		{
       
   797 		case 10: // 110 - Response stale
       
   798 		case 11: // 111 - Revalidation failed
       
   799 		case 12: // 112 - Disconnected operation
       
   800 		case 13: // 113 - Heuristic expiration
       
   801 		case 99: // 199 - Miscellaneous warning
       
   802 			convertedCode = warnCode + 100;
       
   803 			break;
       
   804 		case 14: // 214 - Tranformation applied
       
   805 			convertedCode = warnCode + 200;
       
   806 			break;
       
   807 		// The following warning codes are UAProf specific
       
   808 		case 16: // 100 - OK
       
   809 		case 17: // 101 - Used stale profile
       
   810 		case 18: // 102 - Not used profile
       
   811 			convertedCode = warnCode + 84;
       
   812 			break;
       
   813 		case 32: // 200 - Not applied
       
   814 		case 33: // 201 - Content selection applied
       
   815 		case 34: // 202 - Content generation applied
       
   816 		case 35: // 203 - Transformation applied
       
   817 			convertedCode = warnCode + 168;
       
   818 			break;
       
   819 		default:
       
   820 			convertedCode = warnCode;
       
   821 			break;
       
   822 		}
       
   823 	// Add the value as an integer part
       
   824 	SetNewIntegerPartL(aHeader, 0, convertedCode);
       
   825 	}
       
   826 	
       
   827 void CWspHeaderReader::DecodeGenericNewStringValueL(RHeaderField& aHeader) const
       
   828 	{
       
   829 	TPtrC8 rawHeaderData;
       
   830 	aHeader.RawDataL(rawHeaderData);
       
   831 
       
   832 	TInt startPos = 0;
       
   833 	TInt separatorPos = 0;
       
   834 	TInt ii = 0;
       
   835 	// Loop through all the parts separated by the header field name
       
   836 	do
       
   837 		{
       
   838 		TPtrC8 rawData(rawHeaderData.Mid(startPos));
       
   839 		separatorPos = rawData.Locate((TUint8)(aHeader.Name().Index(WSP::Table) + KTopBitMask));
       
   840 		if(separatorPos!=KErrNotFound)
       
   841 			rawData.Set(rawHeaderData.Mid(startPos, separatorPos));
       
   842 
       
   843 		CheckLengthL(rawData, 1);
       
   844 		TWspPrimitiveDecoder wspDecoder(rawData);
       
   845 		if( !(CheckNullDesPartL(aHeader, rawData, ii)) )
       
   846 			{
       
   847 			AddNewDecoderStringPartL(aHeader, wspDecoder, ii);
       
   848 			}
       
   849 
       
   850 		++ii;
       
   851 		startPos += (separatorPos + 1);
       
   852 		} while( separatorPos != KErrNotFound );
       
   853 	}
       
   854 
       
   855 void CWspHeaderReader::DecodeGenericDateValueL(RHeaderField& aHeader) const
       
   856 	{
       
   857 	TPtrC8 rawData;
       
   858 	aHeader.RawDataL(rawData);
       
   859 	CheckLengthL(rawData, 1);
       
   860 	TWspPrimitiveDecoder wspDecoder(rawData);
       
   861 	if( wspDecoder.VarType() == TWspPrimitiveDecoder::ELengthVal )
       
   862 		{
       
   863 		TDateTime dateTime(1970, EJanuary, 0, 0, 0, 0, 0);
       
   864 		User::LeaveIfError(wspDecoder.Date(dateTime));
       
   865 		SetNewDatePartL(aHeader, 0, dateTime);
       
   866 		}
       
   867 	else
       
   868 		User::Leave(KErrCorrupt);
       
   869 	}
       
   870 
       
   871 void CWspHeaderReader::DecodeGenericFieldNameL(RHeaderField& aHeader) const
       
   872 	{
       
   873 	TPtrC8 rawHeaderData;
       
   874 	aHeader.RawDataL(rawHeaderData);
       
   875 	TInt startPos = 0;
       
   876 	TInt separatorPos = 0;
       
   877 	TInt ii = 0;
       
   878 	// Loop through all the parts separated by the header field name
       
   879 	do
       
   880 		{
       
   881 		TPtrC8 rawData(rawHeaderData.Mid(startPos));
       
   882 		separatorPos = rawData.Locate((TUint8)(aHeader.Name().Index(WSP::Table) + KTopBitMask));
       
   883 		if(separatorPos!=KErrNotFound)
       
   884 			rawData.Set(rawHeaderData.Mid(startPos, separatorPos));
       
   885 
       
   886 		CheckLengthL(rawData, 1);
       
   887 		TWspPrimitiveDecoder wspDecoder(rawData);
       
   888 		switch( wspDecoder.VarType() )
       
   889 			{
       
   890 			case TWspPrimitiveDecoder::EString:
       
   891 				{
       
   892 				AddNewDecoderStringPartL(aHeader, wspDecoder, ii);
       
   893 				} break;
       
   894 			case TWspPrimitiveDecoder::E7BitVal:
       
   895 				{
       
   896 				TUint8 fieldNameToken = 0;
       
   897 				User::LeaveIfError(wspDecoder.Val7Bit(fieldNameToken));
       
   898 				RStringF fieldNameStr = iStrPool.StringF(fieldNameToken, iStrTable);
       
   899 				SetFStringPartL(aHeader, ii, fieldNameStr);
       
   900 				} break;
       
   901 			default:
       
   902 				User::Leave(KErrCorrupt);
       
   903 				break;
       
   904 			}
       
   905 
       
   906 		++ii;
       
   907 		startPos += (separatorPos + 1);
       
   908 		} while( separatorPos != KErrNotFound );
       
   909 	}
       
   910 
       
   911 TInt CWspHeaderReader::DecodeGenericSingleParameterL(TPtrC8& aRawParamBlock, CHeaderFieldPart& aHeaderFieldPart) const
       
   912 	{
       
   913 	TWspPrimitiveDecoder wspDecoder(aRawParamBlock);
       
   914 	TInt bytesRead = 0;
       
   915 	switch( wspDecoder.VarType() )
       
   916 		{
       
   917 		// This is a typed parameter
       
   918 		case TWspPrimitiveDecoder::ELengthVal:
       
   919 		case TWspPrimitiveDecoder::E7BitVal:
       
   920 			{
       
   921 			DecodeWellKnownParamTokenL(wspDecoder, bytesRead, aRawParamBlock, aHeaderFieldPart);
       
   922 			} break;
       
   923 		// This is an untyped parameter
       
   924 		case TWspPrimitiveDecoder::EString:
       
   925 			{
       
   926 			DecodeUntypedParamL(wspDecoder, bytesRead, aRawParamBlock, aHeaderFieldPart);
       
   927 			} break;
       
   928 		default:
       
   929 			User::Leave(KErrCorrupt);
       
   930 			break;
       
   931 		}
       
   932 	return bytesRead;
       
   933 	}
       
   934 
       
   935 void CWspHeaderReader::DecodeWellKnownParamTokenL(TWspPrimitiveDecoder& aDecoder, TInt& aBytesRead,
       
   936 												  TPtrC8& aRawParamBlock, CHeaderFieldPart& aHeaderFieldPart) const
       
   937 	{
       
   938 	TInt err = 0;
       
   939 	TUint32 parameterToken = 0;
       
   940 	aBytesRead = aDecoder.Integer(parameterToken);
       
   941 	THTTPHdrVal paramValue;
       
   942 	RStringF paramDesValue;
       
   943 	CleanupClosePushL(paramDesValue);
       
   944 	RStringF paramName = iStrPool.StringF(parameterToken, WSPParam::Table);
       
   945 	switch( parameterToken )
       
   946 		{
       
   947 		case WSPParam::EQ:
       
   948 			{
       
   949 			// Decode Q value
       
   950 			TUint32 qIntValue = 0;
       
   951 			err = aDecoder.UintVar(qIntValue);
       
   952 			User::LeaveIfError(err);
       
   953 			aBytesRead += err;
       
   954 			TReal q;
       
   955 			TInt numDecimals = 0;
       
   956 			TBuf8<KMaxNumQDigits> qDesC;
       
   957 			if( qIntValue > 100 )
       
   958 				{
       
   959 				// Value is -100 and then divide by 1000
       
   960 				qIntValue -= 100;
       
   961 				q = ((TReal)(qIntValue/1000.));
       
   962 				numDecimals = 3;
       
   963 				}
       
   964 			else
       
   965 				{
       
   966 				// Value is -1 and then divide by 100
       
   967 				--qIntValue;
       
   968 				if( qIntValue%10 ==0 )
       
   969 					numDecimals = 1;
       
   970 				else
       
   971 					numDecimals = 2;
       
   972 				q = ((TReal)(qIntValue/100.));
       
   973 				}
       
   974 			TRealFormat realFt(KMaxNumQDigits,numDecimals); // set max width and 3 decimal places
       
   975 			// always use a decimal separator rather than the one supplied 
       
   976 			// by the current locale
       
   977 			realFt.iPoint = TChar('.'); 
       
   978 			qDesC.Num(q, realFt);
       
   979 			paramDesValue = iStrPool.OpenFStringL(qDesC);
       
   980 			paramValue.SetStrF(paramDesValue);
       
   981 			} break;
       
   982 		case WSPParam::ECharset:
       
   983 			{
       
   984 			if( aRawParamBlock[aBytesRead] == 128 )
       
   985 				{
       
   986 				paramDesValue = iStrPool.StringF(WSPStdConstants::EAny, WSPStdConstants::Table);
       
   987 				paramValue.SetStrF(paramDesValue);
       
   988 				// Need to call Integer to update offset in WSP Decoder
       
   989 				TUint8 updateDecoder =  0;
       
   990 				err = aDecoder.Val7Bit(updateDecoder);
       
   991 				User::LeaveIfError(err);
       
   992 				aBytesRead += err;
       
   993 				}
       
   994 			else
       
   995 				{
       
   996 				switch( aDecoder.VarType() )
       
   997 					{
       
   998 					case TWspPrimitiveDecoder::E7BitVal:
       
   999 					case TWspPrimitiveDecoder::ELengthVal:
       
  1000 						{
       
  1001 						TUint32 value = 0;
       
  1002 						err = aDecoder.Integer(value);
       
  1003 						User::LeaveIfError(err);
       
  1004 						aBytesRead += err;
       
  1005 						GetCharacterSetFromValueL(value, paramDesValue);
       
  1006 						paramValue.SetStrF(paramDesValue);
       
  1007 						} break;
       
  1008 					default:
       
  1009 						User::Leave(KErrCorrupt);
       
  1010 						break;
       
  1011 					}
       
  1012 				}
       
  1013 			} break;
       
  1014 		case WSPParam::ELevel:
       
  1015 			{
       
  1016 			// This is a version value
       
  1017 			err = aDecoder.VersionL(iStrPool,paramDesValue);
       
  1018 			User::LeaveIfError(err);
       
  1019 			aBytesRead += err;
       
  1020 			paramValue.SetStrF(paramDesValue);
       
  1021 			} break;
       
  1022 		case WSPParam::EType:
       
  1023 		case WSPParam::ESize:
       
  1024 		case WSPParam::EPadding:
       
  1025 		case WSPParam::ESEC:
       
  1026 		case WSPParam::EMaxAge:
       
  1027 			{
       
  1028 			TUint32 integerValue = 0;
       
  1029 			err = aDecoder.Integer(integerValue);
       
  1030 			User::LeaveIfError(err);
       
  1031 			aBytesRead += err;
       
  1032 			paramValue.SetInt(integerValue);
       
  1033 			} break;
       
  1034 		case WSPParam::ECreationDate:
       
  1035 		case WSPParam::EModificationDate:
       
  1036 		case WSPParam::EReadDate:
       
  1037 			{
       
  1038 			TDateTime dateTime(1970, EJanuary, 0, 0, 0, 0, 0);
       
  1039 			err = aDecoder.Date(dateTime);
       
  1040 			User::LeaveIfError(err);
       
  1041 			aBytesRead += err;
       
  1042 			paramValue.SetDateTime(dateTime);
       
  1043 			}
       
  1044 		case WSPParam::ENameDep:
       
  1045 		case WSPParam::EFilenameDep:
       
  1046 		case WSPParam::EStartDep:
       
  1047 		case WSPParam::EStartInfoDep:
       
  1048 		case WSPParam::ECommentDep:
       
  1049 		case WSPParam::EDomainDep:
       
  1050 		case WSPParam::EPathDep:
       
  1051 			{
       
  1052 			TPtrC8 textString;
       
  1053 			err = aDecoder.String(textString);
       
  1054 			User::LeaveIfError(err);
       
  1055 			aBytesRead += err;
       
  1056 			paramDesValue = iStrPool.OpenFStringL(textString);
       
  1057 			paramValue.SetStrF(paramDesValue);
       
  1058 			} break;
       
  1059 		case WSPParam::EMAC:
       
  1060 		case WSPParam::EName:
       
  1061 		case WSPParam::EFilename:
       
  1062 		case WSPParam::EStart:
       
  1063 		case WSPParam::EStartInfo:
       
  1064 		case WSPParam::EComment:
       
  1065 		case WSPParam::EDomain:
       
  1066 		case WSPParam::EPath:
       
  1067 			{
       
  1068 			// Check if the string has <no-value> ie <octet 0>
       
  1069 			if( aRawParamBlock[aBytesRead] == 0 )
       
  1070 				{
       
  1071 				paramDesValue = iStrPool.OpenFStringL(KNullDesC8());
       
  1072 				paramValue.SetStrF(paramDesValue);
       
  1073 				// Need to call Integer to update offset in WSP Decoder
       
  1074 				TUint32 updateDecoder =  0;
       
  1075 				err = aDecoder.Integer(updateDecoder);
       
  1076 				User::LeaveIfError(err);
       
  1077 				}
       
  1078 			else
       
  1079 				{
       
  1080 				TPtrC8 textString;
       
  1081 				err = aDecoder.String(textString);
       
  1082 				User::LeaveIfError(err);
       
  1083 				paramDesValue = iStrPool.OpenFStringL(textString);
       
  1084 				paramValue.SetStrF(paramDesValue);
       
  1085 				}
       
  1086 			aBytesRead += err;
       
  1087 			} break;
       
  1088 		case WSPParam::EDifferences:
       
  1089 			{
       
  1090 			aBytesRead += DecodeGenericParamTokenL(aDecoder, iStrTable, paramValue, paramDesValue);
       
  1091 			} break;
       
  1092 		case WSPParam::EContentTypeType:
       
  1093 			{
       
  1094 			aBytesRead += DecodeGenericParamTokenL(aDecoder, WSPContentTypes::Table, paramValue, paramDesValue);
       
  1095 			} break;
       
  1096 		case WSPParam::ESecure:
       
  1097 			{
       
  1098 			// <octet 0> no-value
       
  1099 			paramDesValue = iStrPool.OpenFStringL(KNullDesC8());
       
  1100 			paramValue.SetStrF(paramDesValue);
       
  1101 			// Need to call Integer to update offset in WSP Decoder
       
  1102 			TUint32 updateDecoder =  0;
       
  1103 			err = aDecoder.Integer(updateDecoder);
       
  1104 			User::LeaveIfError(err);
       
  1105 			aBytesRead += err;
       
  1106 			} break;
       
  1107 		default:
       
  1108 			User::Leave(KErrCorrupt);
       
  1109 			break;
       
  1110 		}
       
  1111 
       
  1112 	// Add the parameter name and value
       
  1113 	TPtrC8 paramDes(paramName.DesC());
       
  1114 	SetNewParamL(aHeaderFieldPart, paramDes, paramValue);
       
  1115 	CleanupStack::PopAndDestroy(&paramDesValue);
       
  1116 	}
       
  1117 
       
  1118 void CWspHeaderReader::DecodeUntypedParamL(TWspPrimitiveDecoder& aDecoder, TInt& aBytesRead,
       
  1119 										   TPtrC8& aRawParamBlock, CHeaderFieldPart& aHeaderFieldPart) const
       
  1120 	{
       
  1121 	TPtrC8 paramName;
       
  1122 	aBytesRead = aDecoder.String(paramName);
       
  1123 	User::LeaveIfError(aBytesRead);
       
  1124 	TWspPrimitiveDecoder paramValueDecoder(aRawParamBlock.Mid(aBytesRead));
       
  1125 	TWspPrimitiveDecoder::TWspHeaderType type = paramValueDecoder.VarType();
       
  1126 	// Check if the first octet is NULL, if it is then the value is a <no-value> string
       
  1127 	if( aRawParamBlock[aBytesRead] == 0 )
       
  1128 		type = TWspPrimitiveDecoder::EString;
       
  1129 
       
  1130 	switch( type )
       
  1131 		{
       
  1132 		case TWspPrimitiveDecoder::ELengthVal:
       
  1133 		case TWspPrimitiveDecoder::E7BitVal:
       
  1134 			{
       
  1135 			TUint32 paramIntValue = 0;
       
  1136 			aBytesRead += paramValueDecoder.Integer(paramIntValue);
       
  1137 			SetNewParamL(aHeaderFieldPart, paramName, paramIntValue);
       
  1138 			} break;
       
  1139 		case TWspPrimitiveDecoder::EString:
       
  1140 		case TWspPrimitiveDecoder::EQuotedString:
       
  1141 			{
       
  1142 			RStringF paramValueStr;
       
  1143 			CleanupClosePushL(paramValueStr);
       
  1144 			// Check if the parameter has a value
       
  1145 			if( aRawParamBlock[aBytesRead] == 0 )
       
  1146 				{
       
  1147 				paramValueStr = iStrPool.OpenFStringL(KNullDesC8());
       
  1148 				++aBytesRead;
       
  1149 				}
       
  1150 			else
       
  1151 				{
       
  1152 				TPtrC8 paramStrValue;
       
  1153 				TInt err = paramValueDecoder.String(paramStrValue);
       
  1154 				paramValueStr = iStrPool.OpenFStringL(paramStrValue);
       
  1155 				User::LeaveIfError(err);
       
  1156 				aBytesRead += err;
       
  1157 				}
       
  1158 			SetNewParamL(aHeaderFieldPart, paramName, paramValueStr);
       
  1159 			CleanupStack::PopAndDestroy(&paramValueStr);
       
  1160 			} break;
       
  1161 		default:
       
  1162 			User::Leave(KErrCorrupt);
       
  1163 			break;
       
  1164 		}
       
  1165 	}
       
  1166 
       
  1167 TInt CWspHeaderReader::DecodeGenericParamTokenL(TWspPrimitiveDecoder& aDecoder, const TStringTable& aStrTable,
       
  1168 											THTTPHdrVal& aParamValue, RStringF& aParamDesValue) const
       
  1169 	{
       
  1170 	TInt err = 0;
       
  1171 	switch( aDecoder.VarType() )
       
  1172 		{
       
  1173 		case TWspPrimitiveDecoder::EString:
       
  1174 			{
       
  1175 			TPtrC8 fieldNameString;
       
  1176 			err = aDecoder.String(fieldNameString);
       
  1177 			User::LeaveIfError(err);
       
  1178 			aParamDesValue = iStrPool.OpenFStringL(fieldNameString);
       
  1179 			aParamValue.SetStrF(aParamDesValue);
       
  1180 			} break;
       
  1181 		case TWspPrimitiveDecoder::E7BitVal:
       
  1182 			{
       
  1183 			TUint8 fieldNameToken = 0;
       
  1184 			err = aDecoder.Val7Bit(fieldNameToken);
       
  1185 			User::LeaveIfError(err);
       
  1186 			aParamDesValue = iStrPool.StringF(fieldNameToken, aStrTable);
       
  1187 			aParamValue.SetStrF(aParamDesValue);
       
  1188 			} break;
       
  1189 		default:
       
  1190 			User::Leave(KErrCorrupt);
       
  1191 			break;
       
  1192 		}
       
  1193 	return err;
       
  1194 	}
       
  1195 
       
  1196 void CWspHeaderReader::DecodeGenericChallengeL(RHeaderField& aHeader) const
       
  1197 	{
       
  1198 	TPtrC8 rawData;
       
  1199 	aHeader.RawDataL(rawData);
       
  1200 	CheckLengthL(rawData, 3);
       
  1201 	TWspPrimitiveDecoder wspDecoder(rawData);
       
  1202 	if( wspDecoder.VarType() != TWspPrimitiveDecoder::ELengthVal )
       
  1203 		User::Leave(KErrCorrupt);
       
  1204 
       
  1205 	TInt lengthValue = 0;
       
  1206 	// Check if the first byte is a length-quote
       
  1207 	TInt bytesProcessed = wspDecoder.LengthVal(lengthValue);
       
  1208 
       
  1209 	// An error may have occured
       
  1210 	User::LeaveIfError(bytesProcessed);
       
  1211 
       
  1212 	// Get the challenge data
       
  1213 	TInt err = 0;
       
  1214 	TBool basic = EFalse;
       
  1215 	TPtrC8 challangeData = rawData.Mid(bytesProcessed);
       
  1216 	// The if the first byte is <Octet 128> then it is the Basic scheme otherwise
       
  1217 	// the scheme is in token text
       
  1218 	if( challangeData[0] == 128 )
       
  1219 		{
       
  1220 		basic = ETrue;
       
  1221 		SetFStringPartL(aHeader, 0, iStrPool.StringF(WSPStdConstants::EBasic, WSPStdConstants::Table));
       
  1222 		// Need to call Integer to update offset in WSP Decoder
       
  1223 		TUint32 updateDecoder =  0;
       
  1224 		err = wspDecoder.Integer(updateDecoder);
       
  1225 		User::LeaveIfError(err);
       
  1226 		}
       
  1227 	else
       
  1228 		err = AddNewDecoderStringPartL(aHeader, wspDecoder);
       
  1229 
       
  1230 	bytesProcessed += err;
       
  1231 
       
  1232 	// Get the second part which should be a text string
       
  1233 	// First octet can be '0' ie No-value
       
  1234 	CHeaderFieldPart* fieldPart = NULL;
       
  1235 	if( rawData[bytesProcessed] == 0 )
       
  1236 		{
       
  1237 		fieldPart = &(SetNewFStringPartL(aHeader, 1, KNullDesC8()));
       
  1238 		// Need to call Integer to update offset in WSP Decoder
       
  1239 		TUint32 updateDecoder =  0;
       
  1240 		err = wspDecoder.Integer(updateDecoder);
       
  1241 		User::LeaveIfError(err);
       
  1242 		}
       
  1243 	else
       
  1244 		{
       
  1245 		TPtrC8 realmValue;
       
  1246 		err = wspDecoder.String(realmValue);
       
  1247 		User::LeaveIfError(err);
       
  1248 		fieldPart = &(SetNewFStringPartL(aHeader, 1, realmValue));
       
  1249 		}
       
  1250 	bytesProcessed += err;
       
  1251 
       
  1252 	// Check for parameters and process them
       
  1253 	if( fieldPart == NULL || !basic )
       
  1254 		{
       
  1255 		while( bytesProcessed < rawData.Length() )
       
  1256 			{
       
  1257 			TPtrC8 parameterBlock(rawData.Mid(bytesProcessed));
       
  1258 			bytesProcessed += DecodeGenericSingleParameterL(parameterBlock, *fieldPart);
       
  1259 			}
       
  1260 		}
       
  1261 	}
       
  1262 
       
  1263 void CWspHeaderReader::GetCharacterSetFromValueL(TInt aValue, RStringF& aCharSetStr) const
       
  1264 	{
       
  1265 	TInt charSetToken = 0;
       
  1266 	const TStringTable& strTable = WSPCharacterSets::Table;
       
  1267 	switch( aValue )
       
  1268 		{
       
  1269 		case 0x07EA:
       
  1270 			charSetToken = WSPCharacterSets::EBig5;
       
  1271 			break;
       
  1272 		case 0x03E8:
       
  1273 			charSetToken = WSPCharacterSets::EIso10646ucs2;
       
  1274 			break;
       
  1275 		case 0x04:
       
  1276 			charSetToken = WSPCharacterSets::EIso88591;
       
  1277 			break;
       
  1278 		case 0x05:
       
  1279 			charSetToken = WSPCharacterSets::EIso88592;
       
  1280 			break;
       
  1281 		case 0x06:
       
  1282 			charSetToken = WSPCharacterSets::EIso88593;
       
  1283 			break;
       
  1284 		case 0x07:
       
  1285 			charSetToken = WSPCharacterSets::EIso88594;
       
  1286 			break;
       
  1287 		case 0x08:
       
  1288 			charSetToken = WSPCharacterSets::EIso88595;
       
  1289 			break;
       
  1290 		case 0x09:
       
  1291 			charSetToken = WSPCharacterSets::EIso88596;
       
  1292 			break;
       
  1293 		case 0x0A:
       
  1294 			charSetToken = WSPCharacterSets::EIso88597;
       
  1295 			break;
       
  1296 		case 0x0B:
       
  1297 			charSetToken = WSPCharacterSets::EIso88598;
       
  1298 			break;
       
  1299 		case 0x0C:
       
  1300 			charSetToken = WSPCharacterSets::EIso88599;
       
  1301 			break;
       
  1302 		case 0x11:
       
  1303 			charSetToken = WSPCharacterSets::EShiftJIS;
       
  1304 			break;
       
  1305 		case 0x03:
       
  1306 			charSetToken = WSPCharacterSets::EUsAscii;
       
  1307 			break;
       
  1308 		case 0x6A:
       
  1309 			charSetToken = WSPCharacterSets::EUtf8;
       
  1310 			break;
       
  1311 		default:
       
  1312 			User::Leave(KErrCorrupt);
       
  1313 			break;
       
  1314 		}
       
  1315 	aCharSetStr = iStrPool.StringF(charSetToken, strTable);
       
  1316 	}
       
  1317 
       
  1318 // Generic methods
       
  1319 
       
  1320 CHeaderFieldPart& CWspHeaderReader::SetNewPartL(RHeaderField& aHeader, TInt aPartIndex, THTTPHdrVal& aPartVal) const
       
  1321 	{
       
  1322 	CHeaderFieldPart* part = CHeaderFieldPart::NewL(aPartVal);
       
  1323 	CleanupStack::PushL(part);
       
  1324 	aHeader.SetPartL(part, aPartIndex);
       
  1325 	CleanupStack::Pop(part);
       
  1326 	return *part;
       
  1327 	}
       
  1328 
       
  1329 CHeaderFieldPart& CWspHeaderReader::SetNewIntegerPartL(RHeaderField& aHeader, TInt aPartIndex, TInt aValue) const
       
  1330 	{
       
  1331 	THTTPHdrVal partVal(aValue);
       
  1332 	CHeaderFieldPart& part = SetNewPartL(aHeader, aPartIndex, partVal);
       
  1333 	return part;
       
  1334 	}
       
  1335 
       
  1336 CHeaderFieldPart& CWspHeaderReader::SetNewFStringPartL(RHeaderField& aHeader, TInt aPartIndex, TPtrC8 aValue) const
       
  1337 	{
       
  1338 	RStringF partStr = iStrPool.OpenFStringL(aValue);
       
  1339 	CleanupClosePushL(partStr);
       
  1340 	THTTPHdrVal partVal(partStr);
       
  1341 	CHeaderFieldPart& part = SetNewPartL(aHeader, aPartIndex, partVal);
       
  1342 	CleanupStack::PopAndDestroy(&partStr);
       
  1343 	return part;
       
  1344 	}
       
  1345 
       
  1346 CHeaderFieldPart& CWspHeaderReader::SetNewStringPartL(RHeaderField& aHeader, TInt aPartIndex, TPtrC8 aValue) const
       
  1347 	{
       
  1348 	RString partStr = iStrPool.OpenStringL(aValue);
       
  1349 	CleanupClosePushL(partStr);
       
  1350 	THTTPHdrVal partVal(partStr);
       
  1351 	CHeaderFieldPart& part = SetNewPartL(aHeader, aPartIndex, partVal);
       
  1352 	CleanupStack::PopAndDestroy(&partStr);
       
  1353 	return part;
       
  1354 	}
       
  1355 
       
  1356 CHeaderFieldPart& CWspHeaderReader::SetFStringPartL(RHeaderField& aHeader, TInt aPartIndex, RStringF aStrVal) const
       
  1357 	{
       
  1358 	// Check if a string was found
       
  1359 	if( aStrVal.DesC().Length() == 0 )
       
  1360 		User::Leave(KErrCorrupt);
       
  1361 
       
  1362 	THTTPHdrVal partVal(aStrVal);
       
  1363 	CHeaderFieldPart& part = SetNewPartL(aHeader, aPartIndex, partVal);
       
  1364 	return part;
       
  1365 	}
       
  1366 
       
  1367 CHeaderFieldPart& CWspHeaderReader::SetNewDatePartL(RHeaderField& aHeader, TInt aPartIndex, TDateTime& aDate) const
       
  1368 	{
       
  1369 	THTTPHdrVal partVal(aDate);
       
  1370 	CHeaderFieldPart& part = SetNewPartL(aHeader, aPartIndex, partVal);
       
  1371 	return part;
       
  1372 	}
       
  1373 
       
  1374 CHeaderFieldParam& CWspHeaderReader::SetNewParamL(CHeaderFieldPart& aHeaderPart, TPtrC8 aParamName, THTTPHdrVal aParamValue) const
       
  1375 	{
       
  1376 	RStringF paramNameStr = iStrPool.OpenFStringL(aParamName);
       
  1377 	CleanupClosePushL(paramNameStr);
       
  1378 	CHeaderFieldParam* param = CHeaderFieldParam::NewL(paramNameStr, aParamValue);
       
  1379 	CleanupStack::PushL(param);
       
  1380 	aHeaderPart.AddParamL(param);
       
  1381 	CleanupStack::Pop(param);
       
  1382 	CleanupStack::PopAndDestroy(&paramNameStr);
       
  1383 	return *param;
       
  1384 	}
       
  1385 
       
  1386 TBool CWspHeaderReader::CheckNullDesPartL(RHeaderField& aHeader, TPtrC8& aRawData, TInt aPartIndex) const
       
  1387 	{
       
  1388 	TUint8 firstByte = aRawData[0];
       
  1389 	if( firstByte == 0 )
       
  1390 		{
       
  1391 		SetNewFStringPartL(aHeader, aPartIndex, KNullDesC8());
       
  1392 		return ETrue;
       
  1393 		}
       
  1394 	return EFalse;
       
  1395 	}
       
  1396 
       
  1397 TInt CWspHeaderReader::AddNewDecoderStringPartL(RHeaderField& aHeader, TWspPrimitiveDecoder& aDecoder, TInt aIndex) const
       
  1398 	{
       
  1399 	TPtrC8 buffer;
       
  1400 	TInt err = aDecoder.String(buffer);
       
  1401 	User::LeaveIfError(err);
       
  1402 	SetNewFStringPartL(aHeader, aIndex, buffer);
       
  1403 	return err;
       
  1404 	}
       
  1405 
       
  1406 // Implementation of CWspDefaultHdrReader
       
  1407 //-------------------------------------------------------------------------
       
  1408 
       
  1409 CWspDefaultHdrReader::~CWspDefaultHdrReader()
       
  1410 	{
       
  1411 	}
       
  1412 
       
  1413 CWspDefaultHdrReader* CWspDefaultHdrReader::NewL(RStringPool aStrPool)
       
  1414 	{
       
  1415 	return new(ELeave)CWspDefaultHdrReader(aStrPool);
       
  1416 	}
       
  1417 
       
  1418 CWspDefaultHdrReader* CWspDefaultHdrReader::NewLC(RStringPool aStrPool)
       
  1419 	{
       
  1420 	CWspDefaultHdrReader* self = CWspDefaultHdrReader::NewL(aStrPool);
       
  1421 	CleanupStack::PushL(self);
       
  1422 	return self;
       
  1423 	}
       
  1424 
       
  1425 CWspDefaultHdrReader::CWspDefaultHdrReader(RStringPool aStrPool)
       
  1426 	: iStrPool(aStrPool)
       
  1427 	{
       
  1428 	}
       
  1429 
       
  1430 void CWspDefaultHdrReader::DecodeHeaderL(RHeaderField& aHeader)
       
  1431 	{
       
  1432 	// Get and store the header field name
       
  1433 	TPtrC8 headerField(aHeader.Name().DesC());
       
  1434 
       
  1435 	// Decode the header as a text-string
       
  1436 	TPtrC8 rawHeaderData;
       
  1437 	aHeader.RawDataL(rawHeaderData);
       
  1438 
       
  1439 	TInt startPos = 0;
       
  1440 	TInt separatorPos = 0;
       
  1441 	TInt ii = 0;
       
  1442 	// Loop through all the parts separated by the header field name
       
  1443 	do
       
  1444 		{
       
  1445 		TPtrC8 rawData(rawHeaderData.Mid(startPos));
       
  1446 		separatorPos = rawData.FindF(headerField);
       
  1447 		if(separatorPos!=KErrNotFound)
       
  1448 			rawData.Set(rawHeaderData.Mid(startPos, separatorPos));
       
  1449 
       
  1450 		// Check that the length of the data is at least 1
       
  1451 		if( rawData.Length() < 1 )
       
  1452 			User::Leave(KErrCorrupt);
       
  1453 
       
  1454 		// Check if the data is an empty string which should only have a NULL terminator
       
  1455 		// otherwise extract the text-string from the primitive decoder
       
  1456 		TUint8 firstByte = rawData[0];
       
  1457 		TWspPrimitiveDecoder wspDecoder(rawData);
       
  1458 		TPtrC8 buffer;
       
  1459 		if( firstByte == 0 )
       
  1460 			buffer.Set(KNullDesC8());
       
  1461 		else
       
  1462 			User::LeaveIfError(wspDecoder.String(buffer));
       
  1463 
       
  1464 		// Create a header part from the decoded buffer and add the part to the header field
       
  1465 		RStringF partStr = iStrPool.OpenFStringL(buffer);
       
  1466 		CleanupClosePushL(partStr);
       
  1467 		THTTPHdrVal partVal(partStr);
       
  1468 		CHeaderFieldPart* part = CHeaderFieldPart::NewL(partVal);
       
  1469 		CleanupStack::PushL(part);
       
  1470 		aHeader.SetPartL(part, ii);
       
  1471 		CleanupStack::Pop(part);
       
  1472 		CleanupStack::PopAndDestroy(&partStr);
       
  1473 
       
  1474 		++ii;
       
  1475 		startPos += (separatorPos + headerField.Length() + 1);
       
  1476 		} while( separatorPos != KErrNotFound );
       
  1477 	}