genericservices/httputils/inetprottextutils/inetprottextutils.cpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericservices/httputils/inetprottextutils/inetprottextutils.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,830 @@
+// 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:
+//
+
+#include "inetprottextutils.h"
+
+#include "inetprottextutilslocal.h"
+#include <uriutilscommon.h>
+
+// Panic category
+//
+#ifdef _DEBUG
+	_LIT(KTextUtilsPanicCategory, "IPTXTUTL"); 
+#endif
+
+const TUint KZeroChar		= '0';
+const TUint KAChar			= 'A';
+const TUint	KQuote			= '"';
+const TUint KMinusSign		= '-';
+const TInt KMaxTIntDecimalDigits = 11; // KMaxTInt  => "-2147483648" 
+const TInt KMaxTIntDividedByTen = KMaxTInt/10;
+
+#define KHorizTab 0x09
+#define KSpace 0x20
+#define KZero 0x30
+#define KNine 0x39
+#define KDecimal 0x2E
+
+
+const TInt KMaxNumberSize	= 32;	// includes '-' sign
+
+/**
+	Removes any contiguous whitespace at the extremes of the data, as specified
+	by aMode. Whitespace is defined by the functions TChar::IsSpace() - white
+	space includes spaces, tabs, and separators (e.g. new line).
+	
+	@param			aData	A descriptor pointer with the data.
+	@param			aMode	The specified removal mode.
+	@return			The number of consumed whitespace characters. If the data is
+	empty or the data is all whitespace the error code KUriUtilsErrEmptyData is
+	returned.
+*/
+EXPORT_C TInt InetProtTextUtils::RemoveWhiteSpace(TPtrC8& aData, TRemoveMode aMode)
+	{
+	TInt consumed = DoRemoveWhiteSpace(aData, aMode);
+	if( consumed == KUriUtilsErrEmptyData )
+		{
+		// Either empty data or all whitespace
+		aData.Set(KNullDesC8());
+		}
+	return consumed;
+	}
+
+/**
+	Removes any contiguous whitespace at the extremes of the data, as specified
+	by aMode. Whitespace is defined by the functions TChar::IsSpace() - white
+	space includes spaces, tabs, and separators (e.g. new line).
+	
+	@param			aData	A descriptor pointer with the data.
+	@param			aMode	The specified removal mode.
+	@return			The number of consumed whitespace characters. If the data is
+	empty or the data is all whitespace the error code KUriUtilsErrEmptyData is
+	returned.
+*/
+EXPORT_C TInt InetProtTextUtils::RemoveWhiteSpace(TPtrC16& aData, TRemoveMode aMode)
+	{
+	TInt consumed = DoRemoveWhiteSpace(aData, aMode);
+	if( consumed == KUriUtilsErrEmptyData )
+		{
+		// Either empty data or all whitespace
+		aData.Set(KNullDesC16());
+		}
+	return consumed;
+	}
+
+/**
+	Converts an integer value into its decimal character representation.
+	
+	@param			aInt		An integer value.	
+	@param			aBuffer		An output argument of a pointer to a data buffer
+	that will contain the character representation of the integer value.
+*/
+EXPORT_C void InetProtTextUtils::ConvertIntToDescriptorL(TInt aInt, HBufC8*& aBuffer)
+	{
+	DoConvertIntToDescriptorL(aInt, aBuffer, EDecimal);
+	}
+
+/**
+	Converts an integer value into its decimal character representation.
+	
+	@param			aInt		An integer value.	
+	@param			aBuffer		An output argument of a pointer to a data buffer
+	that will contain the character representation of the integer value.
+*/
+EXPORT_C void InetProtTextUtils::ConvertIntToDescriptorL(TInt aInt, HBufC16*& aBuffer)
+	{
+	DoConvertIntToDescriptorL(aInt, aBuffer, EDecimal);
+	}
+
+/**
+	Converts the character representation of an integer into its numeric value.
+	Preceeding whitespace is ignored and the integer is delimited by either the
+	end of the data, whitespace or any other character other than 0 to 9.
+	
+	@param			aData	A descriptor pointer with the data.
+	@param			aInt	An output argument in which the numeric value of the
+	data is placed.
+	@return			The number of consumed characters that contributed to the 
+					integer value, including any whitespace before the integer. 
+					If the data is empty the error code KUriUtilsErrEmptyData 
+					is returned. If there are no digits at the beginning of the
+					data the error code KUriUtilsErrNoIntergerInData is returned.
+*/
+EXPORT_C TInt InetProtTextUtils::ConvertDescriptorToInt(const TDesC8& aData, TInt& aInt)
+	{
+	// Do conversion and return number of consumed characters
+	return DoConvertDescriptorToInt(TPtrC8(aData), aInt, EDecimal);
+	}
+
+/**
+	Converts the character representation of an integer into its numeric value.
+	Preceeding whitespace is ignored and the integer is delimited by either the
+	end of the data, whitespace or any other character other than 0 to 9.
+	
+	@param			aData	A descriptor pointer with the data.
+	@param			aInt	An output argument in which the numeric value of the
+	data is placed.
+	@return			The number of consumed characters that contributed to the 
+					integer value, including any whitespace before the integer.
+					If the data is empty the error code KUriUtilsErrEmptyData is
+					returned. If there are no digits at the beginning of the data
+					the error code KUriUtilsErrNoIntergerInData is returned.
+*/
+EXPORT_C TInt InetProtTextUtils::ConvertDescriptorToInt(const TDesC16& aData, TInt& aInt)
+	{
+	// Do conversion and return number of consumed characters
+	return DoConvertDescriptorToInt(TPtrC16(aData), aInt, EDecimal);
+	}
+
+/**
+	@internalComponent
+	
+	Converts an integer to its hex representation.
+	
+	@param		aHex	The integer value to convert.
+	@param		aBuffer	An output argument that is set to the buffer containing 
+						the hex representation of aValue.
+	@panic		EInvariantFalse	The integer value was too big.
+*/
+EXPORT_C void InetProtTextUtils::ConvertHexToDescriptorL(TInt aHex, HBufC8*& aBuffer)
+	{
+	DoConvertIntToDescriptorL(aHex, aBuffer, EHex);
+	}
+
+/**
+	@internalComponent
+	
+	Converts an integer to its hex representation.
+	
+	@param		aHex	The integer value to convert.
+	@param		aBuffer	An output argument that is set to the buffer containing 
+						the hex representation of aValue.
+	@panic		EInvariantFalse	The integer value was too big.
+*/
+EXPORT_C void InetProtTextUtils::ConvertHexToDescriptorL(TInt aHex, HBufC16*& aBuffer)
+	{
+	DoConvertIntToDescriptorL(aHex, aBuffer, EHex);
+	}
+
+/**
+	@internalComponent
+	
+	Descriptor to hex convertor. Searches the descriptor buffer for a hex number
+	representation at the start of the buffer. The hex number is deemed to have 
+	ended when the first non-hex character is found. The numeric value of the 
+	hex number is returned along with the number characters consumed in obtaining
+	the number. The amount of leading whitespace is included in the number of 
+	characters consumed.
+	
+	@param		aData	The descriptor buffer to be parsed.
+	@param		aHex	An output argument set to the numeric value of the 
+						parsed hex number.
+	@return		The number of characters consumed in parsing the hex number. If 
+				the descriptor was empty then KUriUtilsErrEmptyData is returned.
+				If no hex number was parsed then KUriUtilsErrNoIntergerInData is
+				returned.
+*/
+EXPORT_C TInt InetProtTextUtils::ConvertDescriptorToHex(const TDesC8& aData, TInt& aHex)
+	{
+	// Do conversion, returning the number of consumed characters
+	return DoConvertDescriptorToInt(TPtrC8(aData), aHex, EHex);
+	}
+
+/**
+	@internalComponent
+	
+	Descriptor to hex convertor. Searches the descriptor buffer for a hex number
+	representation at the start of the buffer. The hex number is deemed to have 
+	ended when the first non-hex character is found. The numeric value of the 
+	hex number is returned along with the number characters consumed in obtaining
+	the number. The amount of leading whitespace is included in the number of 
+	characters consumed.
+	
+	@param		aData	The descriptor buffer to be parsed.
+	@param		aHex	An output argument set to the numeric value of the 
+						parsed hex number.
+	@return		The number of characters consumed in parsing the hex number. If 
+				the descriptor was empty then KUriUtilsErrEmptyData is returned.
+				If no hex number was parsed then KUriUtilsErrNoIntergerInData is
+				returned.
+*/
+EXPORT_C TInt InetProtTextUtils::ConvertDescriptorToHex(const TDesC16& aData, TInt& aHex)
+	{
+	// Do conversion, returning the number of consumed characters
+	return DoConvertDescriptorToInt(TPtrC16(aData), aHex, EHex);
+	}
+
+/** 
+	Extract a token from the head of the supplied buffer, which is assumed to be
+	a token-list. The tokens are separated by the specified character. Any white
+	space surrounding the token is stripped out.  The number of characters 
+	consumed from the buffer are returned. The buffer is updated to not include
+	the extracted token including the separator.
+	
+	@param			aBuffer		The buffer containing the token-list.
+	@param			aToken		An output argument containing the extracted token.
+	@param			aSeparator	The separator character.
+	@return			The number of characters consumed from the buffer.
+*/
+EXPORT_C TInt InetProtTextUtils::ExtractNextTokenFromList(TPtrC8& aBuffer, TPtrC8& aToken, TChar aSeparator)
+	{
+	return DoExtractNextTokenFromList(aBuffer, aToken, aSeparator);
+	}
+
+/** 
+	Extract a token from the head of the supplied buffer, which is assumed to be
+	a token-list. The tokens are separated by the specified character. Any white
+	space surrounding the token is stripped out.  The number of characters 
+	consumed from the buffer are returned. The buffer is updated to not include
+	the extracted token including the separator.
+	
+	@param			aBuffer		The buffer containing the token-list.
+	@param			aToken		An output argument containing the extracted token.
+	@param			aSeparator	The separator character.
+	@return			The number of characters consumed from the buffer.
+*/
+EXPORT_C TInt InetProtTextUtils::ExtractNextTokenFromList(TPtrC16& aBuffer, TPtrC16& aToken, TChar aSeparator)
+	{
+	return DoExtractNextTokenFromList(aBuffer, aToken, aSeparator);
+	}
+
+/** 
+	Extract a token from the head of the supplied buffer, which is assumed to be
+	a token-list. The tokens are separated by one of the specified characters. 
+	Any white space surrounding the token is stripped out.  The number of 
+	characters consumed from the buffer are returned. The buffer is updated to 
+	not include the extracted token including the separator.
+	
+	@param			aBuffer		The buffer containing the token-list.
+	@param			aToken		An output argument containing the extracted token.
+	@param			aSeparators	The list of separator characters.
+	@return			The number of characters consumed from the buffer.
+*/
+EXPORT_C TInt InetProtTextUtils::ExtractNextTokenFromList(TPtrC8& aBuffer, TPtrC8& aToken, const TDesC8& aSeparators)
+	{
+	TPtrC8 separators = aSeparators;
+	return DoExtractNextTokenFromList(aBuffer, aToken, separators);
+	}
+
+/** 
+	Extract a token from the head of the supplied buffer, which is assumed to be
+	a token-list. The tokens are separated by one of the specified characters. 
+	Any white space surrounding the token is stripped out.  The number of 
+	characters consumed from the buffer are returned. The buffer is updated to 
+	not include the extracted token including the separator.
+	
+	@param			aBuffer		The buffer containing the token-list.
+	@param			aToken		An output argument containing the extracted token.
+	@param			aSeparators	The list of separator characters.
+	@return			The number of characters consumed from the buffer.
+*/
+EXPORT_C TInt InetProtTextUtils::ExtractNextTokenFromList(TPtrC16& aBuffer, TPtrC16& aToken, const TDesC16& aSeparators)
+	{
+	TPtrC16 separators = aSeparators;
+	return DoExtractNextTokenFromList(aBuffer, aToken, separators);
+	}
+
+/**	
+	Extract a quoted string value from the head of the supplied buffer. Anything
+	outside the quotes is discarded and the quotes themselves are not included 
+	in the returned string.
+	
+	@param			aBuffer			The buffer containing the quoted.
+	@param			aQuotedString	An output argument containing the extracted
+									string.
+	@return			The number of characters consumed from the buffer.
+*/
+EXPORT_C TInt InetProtTextUtils::ExtractQuotedStringL(TPtrC8& aBuffer, TPtrC8& aQuotedString)
+	{
+	return DoExtractQuotedStringL(aBuffer, aQuotedString);
+	}
+
+/**	
+	Extract a quoted string value from the head of the supplied buffer. Anything
+	outside the quotes is discarded and the quotes themselves are not included 
+	in the returned string.
+	
+	@param			aBuffer			The buffer containing the quoted.
+	@param			aQuotedString	An output argument containing the extracted
+									string.
+	@return			The number of characters consumed from the buffer.
+*/
+EXPORT_C TInt InetProtTextUtils::ExtractQuotedStringL(TPtrC16& aBuffer, TPtrC16& aQuotedString)
+
+	{
+	return DoExtractQuotedStringL(aBuffer, aQuotedString);
+	}
+
+/**	
+	@internalTechnology
+	
+	Extract an integer value from the head of the supplied buffer.
+	
+	@param			aBuffer	The buffer containing the integer value.
+	@param			aIntVal	An output argument in which extracted integer value
+							is placed.
+	@param			aAllowNonWsTerminator	If set to true whitespace is considered as the 
+									terminator, if set to false a non-decimal charecter
+									is considered as terminator.
+	@return			The number of characters in aBuffer after the integer.
+	@leave			KUriUtilsErrMalformedInteger if the value in aBuffer is not an integer 
+					(ie, contains non-decimal characters, or is too big to fit in a TInt)
+*/
+EXPORT_C TInt InetProtTextUtils::ExtractIntegerValueL(TPtrC8& aBuffer, TInt& aIntVal, TBool aAllowNonWsTerminator)
+	{
+	// Anticipate an empty token by default
+	TPtrC8 data(aBuffer);
+
+	// Trim out any whitespace to the left the integer and check there's something left!
+	InetProtTextUtils::RemoveWhiteSpace(data, InetProtTextUtils::ERemoveLeft);
+	const TInt len = data.Length();
+	TInt retVal = aBuffer.Length() -  len; // the amount of WS consumed
+	if (len == 0)
+		{
+		// No integer was found - the supplied buffer was all WS!
+		aIntVal = 0;
+		retVal = aBuffer.Length();
+		aBuffer.Set(data);
+		}
+	else
+		{
+		// Got some data to work with... find out how many digits are present. Assume that the integer
+		// required is a contiguous set of decimal digits followed by WS or the end of the buffer
+		TInt numDigits = 0;
+		TChar ch = KZero; // default most significant digit to zero without affecting the result
+		TBool done = EFalse;
+		while (!done)
+			{
+			// check for the end of the integer. This depends on what is allowed to terminate it.
+			if (aAllowNonWsTerminator)
+				{
+				done = (numDigits == data.Length());
+				if (!done)
+					{
+					ch = data[numDigits];
+					done = ((ch < KZero) || (ch > KNine));
+					}
+				}
+			else
+				{
+				done = (numDigits == data.Length());
+				if (!done)
+					{
+					ch = data[numDigits];
+					done = ((ch == KSpace) || (ch == KHorizTab) || (ch == KDecimal));
+					}
+				}
+
+			// Check that we're getting digits
+			if (!done)
+				{
+				if ((ch < KZero) || (ch > KNine)) // digits 0-9
+					User::Leave(KUriUtilsErrMalformedInteger);
+				++numDigits;
+				}
+			}
+		// Make sure there's no overflow (trivial check)
+		if(numDigits>KMaxTIntDecimalDigits)
+			User::Leave(KUriUtilsErrMalformedInteger);
+		
+		// Now work back, building up the integer
+		aIntVal = 0;
+		for (TInt pos = 0; pos < numDigits; pos++)
+			{
+			// double check no overflow (
+			if(aIntVal>KMaxTIntDividedByTen   ||  //works except for 2147483648 and ...49)
+				( (aIntVal == KMaxTIntDividedByTen)  && (data[pos] >= (KNine-1)) ) // covers those two cases
+				)  
+				User::Leave(KUriUtilsErrMalformedInteger);
+			aIntVal = (data[pos] - KZero) + (aIntVal * 10); // decimal, innit?
+			}
+
+		// work out how much this has consumed
+		retVal += numDigits;
+
+		// Finally ensure the buffer has had the correct amount of data consumed
+		if (len == aBuffer.Length())
+			aBuffer.Set(KNullDesC8()); // there was nothing to the right of the integer
+		else
+			aBuffer.Set(aBuffer.Mid(retVal));
+		}
+	return retVal;
+	}
+
+/*
+ *	Local methods
+ */
+
+/**
+	@internalComponent
+	
+	Does the whitespace removal. Checks the mode and then calls the appropriate
+	functions.
+
+	@warning		Will panic will KUriUtilsErrBadTExtRemoveMode if aMode not valid.
+	@param			aData	A descriptor pointer with the data.
+	@param			aMode	The specified removal mode.
+	@return			The number of consumed whitespace characters. If the data is
+					empty or the data is all whitespace the error code 
+					KUriUtilsErrEmptyData is returned.
+*/
+template<class TPtrCType>
+TInt DoRemoveWhiteSpace(TPtrCType& aData, InetProtTextUtils::TRemoveMode aMode)
+	{
+	TInt consumed = 0;
+	switch( aMode )
+		{
+	case InetProtTextUtils::ERemoveLeft:
+		{
+		consumed = FindWhiteSpaceLeft(aData);
+		if( consumed > 0 )
+			{
+			// Found some whitespace
+			aData.Set(aData.Mid(consumed));
+			}
+		} break;
+	case InetProtTextUtils::ERemoveRight:
+		{
+		consumed = FindWhiteSpaceRight(aData);
+		if( consumed > 0 )
+			{
+			// Found some whitespace
+			aData.Set(aData.Left(aData.Length() - consumed));
+			}
+		} break;
+	case InetProtTextUtils::ERemoveBoth:
+		{
+		// Remove from left first...
+		consumed = FindWhiteSpaceLeft(aData);
+ 		if( consumed != KUriUtilsErrEmptyData )
+			{
+			// Found some whitespace - set the pointer then remove from right
+			aData.Set(aData.Mid(consumed));
+			TInt consumedRight = FindWhiteSpaceRight(aData);
+
+			// To get this far descriptor is non-empty and not all whitespace - no check
+			aData.Set(aData.Left(aData.Length() - consumedRight));
+			consumed += consumedRight;
+			}
+		} break;
+	default:
+		__ASSERT_DEBUG(EFalse, User::Panic(KTextUtilsPanicCategory, KUriUtilsErrBadTextRemoveMode));
+		}
+	return consumed;
+	}
+
+/**
+	@internalComponent
+	
+	Finds the number of contiguous whitespace characters at the 
+	beginning of the data.
+
+	@param			aData	A descriptor pointer with the data.
+	@return			The number of consumed whitespace characters. If the data is
+					empty or the data is all whitespace the error code 
+					KTextUtilsErrEmptyData is returned.
+ */
+template<class TPtrCType>
+TInt FindWhiteSpaceLeft(const TPtrCType& aData)
+	{
+	const TInt length = aData.Length();
+	if( length == 0 )
+		return KUriUtilsErrEmptyData;
+	TInt i = 0;
+	TBool done = EFalse;
+	while( !done && i < length )
+		{
+		TChar current = aData[i];
+		done  = !current.IsSpace();
+		if( !done )
+			++i;
+		}
+	if( i == length )
+		return KUriUtilsErrEmptyData;
+	return i;
+	}
+
+/**
+	@internalComponent
+	
+	Finds the number of contiguous whitespace characters at the end of the data.
+
+	@param			aData	A descriptor pointer with the data.
+	@return			The number of consumed whitespace characters. If the data is
+					empty or the data is all whitespace the error code 
+					KTextUtilsErrEmptyData is returned.
+*/
+template<class TPtrCType>
+TInt FindWhiteSpaceRight(const TPtrCType& aData)
+	{
+	const TInt length = aData.Length();
+	if( length == 0 )
+		return KUriUtilsErrEmptyData;
+	TInt i = 0;
+	TBool done = EFalse;
+	while( !done && i < length )
+		{
+		TChar current = aData[(length-1) - i];
+		done  = !current.IsSpace();
+		if( !done )
+			++i;
+		}
+	if( i == length )
+		return KUriUtilsErrEmptyData;
+	return i;
+	}
+
+/** 
+	Extracts next token from the buffer.
+	
+	@param			aBuffer		The buffer containing the token-list.
+	@param			aToken		An output argument containing the extracted token.
+	@param			aSeparator	The separator character.
+	@return			The number of characters consumed from the buffer.
+*/
+template<class TPtrCType>
+TInt DoExtractNextTokenFromList(TPtrCType& aBuffer, TPtrCType& aToken, TChar aSeparator)
+	{
+	// Anticipate an empty token by default.
+	TInt consumed = 0;
+
+	// Search for the separator
+	const TInt pos = aBuffer.Locate(aSeparator);
+
+	// If the separator was found, take chars upto it. Otherwise use the whole
+	// remaining buffer - implies the last token in the list.
+	if( pos == KErrNotFound )
+		{
+		// Last token - take the whole lot
+		aToken.Set(aBuffer);
+		consumed = aBuffer.Length();
+		}
+	else
+		{
+		// Take upto the separator position for the token, and move the buffer 
+		// past the token.
+		aToken.Set(aBuffer.Left(pos));
+		consumed = pos + 1;	// include the separator
+		}
+	// Set the buffer to move past the extracted token.
+	aBuffer.Set(aBuffer.Mid(consumed));
+
+	// Trim out any whitespace surrounding the token, and return how many charas
+	// were consumed.
+	InetProtTextUtils::RemoveWhiteSpace(aToken, InetProtTextUtils::ERemoveBoth);
+	return consumed;
+	}
+
+/** 
+	Extracts next token from the buffer.
+	
+	@param			aBuffer		The buffer containing the token-list.
+	@param			aToken		An output argument containing the extracted token.
+	@param			aSeparator	The separator.
+	@return			The number of characters consumed from the buffer.
+*/
+template<class TPtrCType>
+TInt DoExtractNextTokenFromList(TPtrCType& aBuffer, TPtrCType& aToken, const TPtrCType& aSeparator)
+	{
+	// Finds the next token in the list, where all the characters in
+	// the separator array are considered to be separators.
+
+	// Anticipate an empty token by default.
+	TInt consumed = 0;
+
+	// Search for separator...
+	const TInt length = aBuffer.Length();
+	TInt pos = 0;
+	TBool found = EFalse;
+	while( !found && pos < length )
+		{
+		// If we find a quoted string, skip over it (and any token
+		// separators within it)
+		if( aBuffer[pos] == KQuote )
+			{
+			for( ++pos; pos < length && aBuffer[pos] != KQuote; ++pos )
+				{}
+			if (pos == length)
+				break; // end of string reached
+			}
+		if( aSeparator.Locate(aBuffer[pos]) != KErrNotFound )
+			found = ETrue;
+		else
+			++pos;
+		}
+
+	// If the separator was found, take chars upto it. Otherwise use the whole
+	// remaining buffer - implies the last token in the list.
+	if( found )
+		{
+		// Take upto the separator position for the token, and move the buffer 
+		// past the token.
+		aToken.Set(aBuffer.Left(pos));
+		consumed = pos + 1;
+		}
+	else
+		{
+		// Last token - take the whole lot
+		aToken.Set(aBuffer);
+		consumed = aBuffer.Length();
+		}
+	// Set the buffer to move past the extracted token.
+	aBuffer.Set(aBuffer.Mid(consumed));
+
+	// Trim out any whitespace surrounding the token, and return how
+	// many characters were extracted.
+	InetProtTextUtils::RemoveWhiteSpace(aToken, InetProtTextUtils::ERemoveBoth);
+	return consumed;
+	}
+
+/**	
+	Extract a quoted string value from the buffer. 
+	
+	@param			aBuffer			The buffer containing the quoted.
+	@param			aQuotedString	An output argument containing the extracted
+									string.
+	@return			The number of characters consumed from the buffer.
+*/
+template<class TPtrCType>
+TInt DoExtractQuotedStringL(TPtrCType& aBuffer, TPtrCType& aQuotedString)
+	{
+	// Find the opening "
+	TInt quotePos1 = aBuffer.Locate(KQuote);
+	if( quotePos1 == KErrNotFound )
+		User::Leave(KUriUtilsErrDecodeMalformedQuotedString);
+
+	// Find the closing "
+	TPtrCType temp = aBuffer.Mid(quotePos1 + 1);	// ignore the "
+	TInt quotePos2 = temp.LocateReverse(KQuote);
+	if( quotePos2 == KErrNotFound )
+		User::Leave(KUriUtilsErrDecodeMalformedQuotedString);
+	
+	// return what's between them and consume the right number of characters from the buffer
+	aQuotedString.Set(temp.Left(quotePos2));
+	TInt consumed = quotePos1 + quotePos2 + 2; // +2 is to consume the quotes themselves
+	aBuffer.Set(aBuffer.Mid(consumed));
+	return consumed;
+	}
+
+/**
+	Converts an integer value into its decimal character representation.
+	
+	@param			aInt		An integer value.	
+	@param			aBuffer		An output argument of a pointer to a data buffer
+	that will contain the character representation of the integer value.
+	@param			aRadix		enum value.	
+*/
+template<class HBufCType>
+void DoConvertIntToDescriptorL(TInt aInt, HBufCType*& aBuffer, TRadix aRadix)
+	{
+	// Create the buffer - max possible size for binary number is 32
+	TBuf8<KMaxNumberSize> buf;
+	buf.SetMax();
+
+	// Is the number -ve?
+	TUint value = aInt;
+	TBool negative = EFalse;
+	if( aInt < 0 )
+		{
+		negative = ETrue;
+		value = -aInt;
+		}
+
+	// Now form the number...
+	TInt index = KMaxNumberSize;
+	do	
+		{
+		// Update the index
+		--index;
+		__ASSERT_DEBUG( index > 0, User::Invariant() );
+
+		// Find the value of the least significant digit
+		TUint q = value/aRadix;
+		TUint c = value - (q*aRadix);
+
+		// Convert digit to character and insert into the buffer.
+		( c > 9 ) ? c += (KAChar-10) : c += KZeroChar;
+		buf[index] = STATIC_CAST(TUint8, c);
+
+		// Update the value left to convert.
+		value = q;
+		} while( value > 0 );
+
+	// Add the '-' sign if number was negative
+	if( negative )
+		buf[--index] = KMinusSign;
+
+	// Create the output buffer...
+	TPtrC8 number = buf.Mid(index);
+	aBuffer = HBufCType::NewL(number.Length());
+	aBuffer->Des().Copy(number);
+	}
+
+/**
+	Converts the character representation of an integer into its numeric value.
+	Preceeding whitespace is ignored and the integer is delimited by either the
+	end of the data, whitespace or any other character other than 0 to 9.
+	
+	@param			aData	A descriptor pointer with the data.
+	@param			aInt	An output argument in which the numeric value of the
+	data is placed.
+	@param			aRadix		enum value.	
+	@return			The number of consumed characters that contributed to the 
+					integer value, including any whitespace before the integer. 
+					If the data is empty the error code KUriUtilsErrEmptyData 
+					is returned. If there are no digits at the beginning of the
+					data the error code KUriUtilsErrNoIntergerInData is returned.
+*/
+template<class TPtrCType>
+TInt DoConvertDescriptorToInt(const TPtrCType& aData, TInt& aInt, TRadix aRadix)
+	{
+	// Remove any whitespace before the digits
+	TPtrCType data = aData;
+	TInt consumed = InetProtTextUtils::RemoveWhiteSpace(data, InetProtTextUtils::ERemoveLeft);
+
+	// Ensure that there are some digits to convert
+	TInt length = data.Length();
+	if( length == 0 )
+		{
+		return KUriUtilsErrEmptyData;
+		}
+
+	// Search for digits and calculate value - stop when non-digit found
+	TInt value = 0;
+	TBool done = EFalse;
+	
+	TBool negative=EFalse;
+
+	if(data[0]==KMinusSign)
+	   {
+		negative=ETrue;
+	   }	
+	
+	TInt i=0;
+	
+	// Length is verifying as user input may be just only '-' sign.
+	if( negative && length > 1 )
+		{
+		i = 1;	
+		}
+	while( !done )
+		{
+		// Get the current char and see if it is a digit
+		TChar c = data[i];
+
+		if( c.IsHexDigit() )
+			{
+			// Need to convert char to its numeric value
+			TInt digit = c - KZeroChar;
+
+			// Was the char in the A-F range?
+			if( digit > 9 )
+				digit = c.GetUpperCase() - (KAChar - 10);
+			
+			if( digit > aRadix )
+				{
+				// The character is too large for the radix - end of data.
+				done = ETrue;
+				}
+			else
+				{
+				// Update running total
+				value *= aRadix;
+				value += digit;
+				}
+			}
+		else
+			{
+			// Non-digit found - we're done!
+			done = ETrue;
+			}
+		// Check for end of data
+		done = done || !(++i < length);
+		}
+	// Set up outputs
+	if( i == 0 )
+		{
+		// No digits found in data - do not set aInt
+		return KUriUtilsErrNoIntegerInData;
+		}
+	// Set the value of the interger
+	if( negative )
+		aInt = -value;
+	else
+		aInt = value;
+
+	// Return consumed characters
+	return i + consumed;
+	}