os/ossrv/genericservices/httputils/inetprottextutils/inetprottextutils.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
//
sl@0
    15
sl@0
    16
#include "inetprottextutils.h"
sl@0
    17
sl@0
    18
#include "inetprottextutilslocal.h"
sl@0
    19
#include <uriutilscommon.h>
sl@0
    20
sl@0
    21
// Panic category
sl@0
    22
//
sl@0
    23
#ifdef _DEBUG
sl@0
    24
	_LIT(KTextUtilsPanicCategory, "IPTXTUTL"); 
sl@0
    25
#endif
sl@0
    26
sl@0
    27
const TUint KZeroChar		= '0';
sl@0
    28
const TUint KAChar			= 'A';
sl@0
    29
const TUint	KQuote			= '"';
sl@0
    30
const TUint KMinusSign		= '-';
sl@0
    31
const TInt KMaxTIntDecimalDigits = 11; // KMaxTInt  => "-2147483648" 
sl@0
    32
const TInt KMaxTIntDividedByTen = KMaxTInt/10;
sl@0
    33
sl@0
    34
#define KHorizTab 0x09
sl@0
    35
#define KSpace 0x20
sl@0
    36
#define KZero 0x30
sl@0
    37
#define KNine 0x39
sl@0
    38
#define KDecimal 0x2E
sl@0
    39
sl@0
    40
sl@0
    41
const TInt KMaxNumberSize	= 32;	// includes '-' sign
sl@0
    42
sl@0
    43
/**
sl@0
    44
	Removes any contiguous whitespace at the extremes of the data, as specified
sl@0
    45
	by aMode. Whitespace is defined by the functions TChar::IsSpace() - white
sl@0
    46
	space includes spaces, tabs, and separators (e.g. new line).
sl@0
    47
	
sl@0
    48
	@param			aData	A descriptor pointer with the data.
sl@0
    49
	@param			aMode	The specified removal mode.
sl@0
    50
	@return			The number of consumed whitespace characters. If the data is
sl@0
    51
	empty or the data is all whitespace the error code KUriUtilsErrEmptyData is
sl@0
    52
	returned.
sl@0
    53
*/
sl@0
    54
EXPORT_C TInt InetProtTextUtils::RemoveWhiteSpace(TPtrC8& aData, TRemoveMode aMode)
sl@0
    55
	{
sl@0
    56
	TInt consumed = DoRemoveWhiteSpace(aData, aMode);
sl@0
    57
	if( consumed == KUriUtilsErrEmptyData )
sl@0
    58
		{
sl@0
    59
		// Either empty data or all whitespace
sl@0
    60
		aData.Set(KNullDesC8());
sl@0
    61
		}
sl@0
    62
	return consumed;
sl@0
    63
	}
sl@0
    64
sl@0
    65
/**
sl@0
    66
	Removes any contiguous whitespace at the extremes of the data, as specified
sl@0
    67
	by aMode. Whitespace is defined by the functions TChar::IsSpace() - white
sl@0
    68
	space includes spaces, tabs, and separators (e.g. new line).
sl@0
    69
	
sl@0
    70
	@param			aData	A descriptor pointer with the data.
sl@0
    71
	@param			aMode	The specified removal mode.
sl@0
    72
	@return			The number of consumed whitespace characters. If the data is
sl@0
    73
	empty or the data is all whitespace the error code KUriUtilsErrEmptyData is
sl@0
    74
	returned.
sl@0
    75
*/
sl@0
    76
EXPORT_C TInt InetProtTextUtils::RemoveWhiteSpace(TPtrC16& aData, TRemoveMode aMode)
sl@0
    77
	{
sl@0
    78
	TInt consumed = DoRemoveWhiteSpace(aData, aMode);
sl@0
    79
	if( consumed == KUriUtilsErrEmptyData )
sl@0
    80
		{
sl@0
    81
		// Either empty data or all whitespace
sl@0
    82
		aData.Set(KNullDesC16());
sl@0
    83
		}
sl@0
    84
	return consumed;
sl@0
    85
	}
sl@0
    86
sl@0
    87
/**
sl@0
    88
	Converts an integer value into its decimal character representation.
sl@0
    89
	
sl@0
    90
	@param			aInt		An integer value.	
sl@0
    91
	@param			aBuffer		An output argument of a pointer to a data buffer
sl@0
    92
	that will contain the character representation of the integer value.
sl@0
    93
*/
sl@0
    94
EXPORT_C void InetProtTextUtils::ConvertIntToDescriptorL(TInt aInt, HBufC8*& aBuffer)
sl@0
    95
	{
sl@0
    96
	DoConvertIntToDescriptorL(aInt, aBuffer, EDecimal);
sl@0
    97
	}
sl@0
    98
sl@0
    99
/**
sl@0
   100
	Converts an integer value into its decimal character representation.
sl@0
   101
	
sl@0
   102
	@param			aInt		An integer value.	
sl@0
   103
	@param			aBuffer		An output argument of a pointer to a data buffer
sl@0
   104
	that will contain the character representation of the integer value.
sl@0
   105
*/
sl@0
   106
EXPORT_C void InetProtTextUtils::ConvertIntToDescriptorL(TInt aInt, HBufC16*& aBuffer)
sl@0
   107
	{
sl@0
   108
	DoConvertIntToDescriptorL(aInt, aBuffer, EDecimal);
sl@0
   109
	}
sl@0
   110
sl@0
   111
/**
sl@0
   112
	Converts the character representation of an integer into its numeric value.
sl@0
   113
	Preceeding whitespace is ignored and the integer is delimited by either the
sl@0
   114
	end of the data, whitespace or any other character other than 0 to 9.
sl@0
   115
	
sl@0
   116
	@param			aData	A descriptor pointer with the data.
sl@0
   117
	@param			aInt	An output argument in which the numeric value of the
sl@0
   118
	data is placed.
sl@0
   119
	@return			The number of consumed characters that contributed to the 
sl@0
   120
					integer value, including any whitespace before the integer. 
sl@0
   121
					If the data is empty the error code KUriUtilsErrEmptyData 
sl@0
   122
					is returned. If there are no digits at the beginning of the
sl@0
   123
					data the error code KUriUtilsErrNoIntergerInData is returned.
sl@0
   124
*/
sl@0
   125
EXPORT_C TInt InetProtTextUtils::ConvertDescriptorToInt(const TDesC8& aData, TInt& aInt)
sl@0
   126
	{
sl@0
   127
	// Do conversion and return number of consumed characters
sl@0
   128
	return DoConvertDescriptorToInt(TPtrC8(aData), aInt, EDecimal);
sl@0
   129
	}
sl@0
   130
sl@0
   131
/**
sl@0
   132
	Converts the character representation of an integer into its numeric value.
sl@0
   133
	Preceeding whitespace is ignored and the integer is delimited by either the
sl@0
   134
	end of the data, whitespace or any other character other than 0 to 9.
sl@0
   135
	
sl@0
   136
	@param			aData	A descriptor pointer with the data.
sl@0
   137
	@param			aInt	An output argument in which the numeric value of the
sl@0
   138
	data is placed.
sl@0
   139
	@return			The number of consumed characters that contributed to the 
sl@0
   140
					integer value, including any whitespace before the integer.
sl@0
   141
					If the data is empty the error code KUriUtilsErrEmptyData is
sl@0
   142
					returned. If there are no digits at the beginning of the data
sl@0
   143
					the error code KUriUtilsErrNoIntergerInData is returned.
sl@0
   144
*/
sl@0
   145
EXPORT_C TInt InetProtTextUtils::ConvertDescriptorToInt(const TDesC16& aData, TInt& aInt)
sl@0
   146
	{
sl@0
   147
	// Do conversion and return number of consumed characters
sl@0
   148
	return DoConvertDescriptorToInt(TPtrC16(aData), aInt, EDecimal);
sl@0
   149
	}
sl@0
   150
sl@0
   151
/**
sl@0
   152
	@internalComponent
sl@0
   153
	
sl@0
   154
	Converts an integer to its hex representation.
sl@0
   155
	
sl@0
   156
	@param		aHex	The integer value to convert.
sl@0
   157
	@param		aBuffer	An output argument that is set to the buffer containing 
sl@0
   158
						the hex representation of aValue.
sl@0
   159
	@panic		EInvariantFalse	The integer value was too big.
sl@0
   160
*/
sl@0
   161
EXPORT_C void InetProtTextUtils::ConvertHexToDescriptorL(TInt aHex, HBufC8*& aBuffer)
sl@0
   162
	{
sl@0
   163
	DoConvertIntToDescriptorL(aHex, aBuffer, EHex);
sl@0
   164
	}
sl@0
   165
sl@0
   166
/**
sl@0
   167
	@internalComponent
sl@0
   168
	
sl@0
   169
	Converts an integer to its hex representation.
sl@0
   170
	
sl@0
   171
	@param		aHex	The integer value to convert.
sl@0
   172
	@param		aBuffer	An output argument that is set to the buffer containing 
sl@0
   173
						the hex representation of aValue.
sl@0
   174
	@panic		EInvariantFalse	The integer value was too big.
sl@0
   175
*/
sl@0
   176
EXPORT_C void InetProtTextUtils::ConvertHexToDescriptorL(TInt aHex, HBufC16*& aBuffer)
sl@0
   177
	{
sl@0
   178
	DoConvertIntToDescriptorL(aHex, aBuffer, EHex);
sl@0
   179
	}
sl@0
   180
sl@0
   181
/**
sl@0
   182
	@internalComponent
sl@0
   183
	
sl@0
   184
	Descriptor to hex convertor. Searches the descriptor buffer for a hex number
sl@0
   185
	representation at the start of the buffer. The hex number is deemed to have 
sl@0
   186
	ended when the first non-hex character is found. The numeric value of the 
sl@0
   187
	hex number is returned along with the number characters consumed in obtaining
sl@0
   188
	the number. The amount of leading whitespace is included in the number of 
sl@0
   189
	characters consumed.
sl@0
   190
	
sl@0
   191
	@param		aData	The descriptor buffer to be parsed.
sl@0
   192
	@param		aHex	An output argument set to the numeric value of the 
sl@0
   193
						parsed hex number.
sl@0
   194
	@return		The number of characters consumed in parsing the hex number. If 
sl@0
   195
				the descriptor was empty then KUriUtilsErrEmptyData is returned.
sl@0
   196
				If no hex number was parsed then KUriUtilsErrNoIntergerInData is
sl@0
   197
				returned.
sl@0
   198
*/
sl@0
   199
EXPORT_C TInt InetProtTextUtils::ConvertDescriptorToHex(const TDesC8& aData, TInt& aHex)
sl@0
   200
	{
sl@0
   201
	// Do conversion, returning the number of consumed characters
sl@0
   202
	return DoConvertDescriptorToInt(TPtrC8(aData), aHex, EHex);
sl@0
   203
	}
sl@0
   204
sl@0
   205
/**
sl@0
   206
	@internalComponent
sl@0
   207
	
sl@0
   208
	Descriptor to hex convertor. Searches the descriptor buffer for a hex number
sl@0
   209
	representation at the start of the buffer. The hex number is deemed to have 
sl@0
   210
	ended when the first non-hex character is found. The numeric value of the 
sl@0
   211
	hex number is returned along with the number characters consumed in obtaining
sl@0
   212
	the number. The amount of leading whitespace is included in the number of 
sl@0
   213
	characters consumed.
sl@0
   214
	
sl@0
   215
	@param		aData	The descriptor buffer to be parsed.
sl@0
   216
	@param		aHex	An output argument set to the numeric value of the 
sl@0
   217
						parsed hex number.
sl@0
   218
	@return		The number of characters consumed in parsing the hex number. If 
sl@0
   219
				the descriptor was empty then KUriUtilsErrEmptyData is returned.
sl@0
   220
				If no hex number was parsed then KUriUtilsErrNoIntergerInData is
sl@0
   221
				returned.
sl@0
   222
*/
sl@0
   223
EXPORT_C TInt InetProtTextUtils::ConvertDescriptorToHex(const TDesC16& aData, TInt& aHex)
sl@0
   224
	{
sl@0
   225
	// Do conversion, returning the number of consumed characters
sl@0
   226
	return DoConvertDescriptorToInt(TPtrC16(aData), aHex, EHex);
sl@0
   227
	}
sl@0
   228
sl@0
   229
/** 
sl@0
   230
	Extract a token from the head of the supplied buffer, which is assumed to be
sl@0
   231
	a token-list. The tokens are separated by the specified character. Any white
sl@0
   232
	space surrounding the token is stripped out.  The number of characters 
sl@0
   233
	consumed from the buffer are returned. The buffer is updated to not include
sl@0
   234
	the extracted token including the separator.
sl@0
   235
	
sl@0
   236
	@param			aBuffer		The buffer containing the token-list.
sl@0
   237
	@param			aToken		An output argument containing the extracted token.
sl@0
   238
	@param			aSeparator	The separator character.
sl@0
   239
	@return			The number of characters consumed from the buffer.
sl@0
   240
*/
sl@0
   241
EXPORT_C TInt InetProtTextUtils::ExtractNextTokenFromList(TPtrC8& aBuffer, TPtrC8& aToken, TChar aSeparator)
sl@0
   242
	{
sl@0
   243
	return DoExtractNextTokenFromList(aBuffer, aToken, aSeparator);
sl@0
   244
	}
sl@0
   245
sl@0
   246
/** 
sl@0
   247
	Extract a token from the head of the supplied buffer, which is assumed to be
sl@0
   248
	a token-list. The tokens are separated by the specified character. Any white
sl@0
   249
	space surrounding the token is stripped out.  The number of characters 
sl@0
   250
	consumed from the buffer are returned. The buffer is updated to not include
sl@0
   251
	the extracted token including the separator.
sl@0
   252
	
sl@0
   253
	@param			aBuffer		The buffer containing the token-list.
sl@0
   254
	@param			aToken		An output argument containing the extracted token.
sl@0
   255
	@param			aSeparator	The separator character.
sl@0
   256
	@return			The number of characters consumed from the buffer.
sl@0
   257
*/
sl@0
   258
EXPORT_C TInt InetProtTextUtils::ExtractNextTokenFromList(TPtrC16& aBuffer, TPtrC16& aToken, TChar aSeparator)
sl@0
   259
	{
sl@0
   260
	return DoExtractNextTokenFromList(aBuffer, aToken, aSeparator);
sl@0
   261
	}
sl@0
   262
sl@0
   263
/** 
sl@0
   264
	Extract a token from the head of the supplied buffer, which is assumed to be
sl@0
   265
	a token-list. The tokens are separated by one of the specified characters. 
sl@0
   266
	Any white space surrounding the token is stripped out.  The number of 
sl@0
   267
	characters consumed from the buffer are returned. The buffer is updated to 
sl@0
   268
	not include the extracted token including the separator.
sl@0
   269
	
sl@0
   270
	@param			aBuffer		The buffer containing the token-list.
sl@0
   271
	@param			aToken		An output argument containing the extracted token.
sl@0
   272
	@param			aSeparators	The list of separator characters.
sl@0
   273
	@return			The number of characters consumed from the buffer.
sl@0
   274
*/
sl@0
   275
EXPORT_C TInt InetProtTextUtils::ExtractNextTokenFromList(TPtrC8& aBuffer, TPtrC8& aToken, const TDesC8& aSeparators)
sl@0
   276
	{
sl@0
   277
	TPtrC8 separators = aSeparators;
sl@0
   278
	return DoExtractNextTokenFromList(aBuffer, aToken, separators);
sl@0
   279
	}
sl@0
   280
sl@0
   281
/** 
sl@0
   282
	Extract a token from the head of the supplied buffer, which is assumed to be
sl@0
   283
	a token-list. The tokens are separated by one of the specified characters. 
sl@0
   284
	Any white space surrounding the token is stripped out.  The number of 
sl@0
   285
	characters consumed from the buffer are returned. The buffer is updated to 
sl@0
   286
	not include the extracted token including the separator.
sl@0
   287
	
sl@0
   288
	@param			aBuffer		The buffer containing the token-list.
sl@0
   289
	@param			aToken		An output argument containing the extracted token.
sl@0
   290
	@param			aSeparators	The list of separator characters.
sl@0
   291
	@return			The number of characters consumed from the buffer.
sl@0
   292
*/
sl@0
   293
EXPORT_C TInt InetProtTextUtils::ExtractNextTokenFromList(TPtrC16& aBuffer, TPtrC16& aToken, const TDesC16& aSeparators)
sl@0
   294
	{
sl@0
   295
	TPtrC16 separators = aSeparators;
sl@0
   296
	return DoExtractNextTokenFromList(aBuffer, aToken, separators);
sl@0
   297
	}
sl@0
   298
sl@0
   299
/**	
sl@0
   300
	Extract a quoted string value from the head of the supplied buffer. Anything
sl@0
   301
	outside the quotes is discarded and the quotes themselves are not included 
sl@0
   302
	in the returned string.
sl@0
   303
	
sl@0
   304
	@param			aBuffer			The buffer containing the quoted.
sl@0
   305
	@param			aQuotedString	An output argument containing the extracted
sl@0
   306
									string.
sl@0
   307
	@return			The number of characters consumed from the buffer.
sl@0
   308
*/
sl@0
   309
EXPORT_C TInt InetProtTextUtils::ExtractQuotedStringL(TPtrC8& aBuffer, TPtrC8& aQuotedString)
sl@0
   310
	{
sl@0
   311
	return DoExtractQuotedStringL(aBuffer, aQuotedString);
sl@0
   312
	}
sl@0
   313
sl@0
   314
/**	
sl@0
   315
	Extract a quoted string value from the head of the supplied buffer. Anything
sl@0
   316
	outside the quotes is discarded and the quotes themselves are not included 
sl@0
   317
	in the returned string.
sl@0
   318
	
sl@0
   319
	@param			aBuffer			The buffer containing the quoted.
sl@0
   320
	@param			aQuotedString	An output argument containing the extracted
sl@0
   321
									string.
sl@0
   322
	@return			The number of characters consumed from the buffer.
sl@0
   323
*/
sl@0
   324
EXPORT_C TInt InetProtTextUtils::ExtractQuotedStringL(TPtrC16& aBuffer, TPtrC16& aQuotedString)
sl@0
   325
sl@0
   326
	{
sl@0
   327
	return DoExtractQuotedStringL(aBuffer, aQuotedString);
sl@0
   328
	}
sl@0
   329
sl@0
   330
/**	
sl@0
   331
	@internalTechnology
sl@0
   332
	
sl@0
   333
	Extract an integer value from the head of the supplied buffer.
sl@0
   334
	
sl@0
   335
	@param			aBuffer	The buffer containing the integer value.
sl@0
   336
	@param			aIntVal	An output argument in which extracted integer value
sl@0
   337
							is placed.
sl@0
   338
	@param			aAllowNonWsTerminator	If set to true whitespace is considered as the 
sl@0
   339
									terminator, if set to false a non-decimal charecter
sl@0
   340
									is considered as terminator.
sl@0
   341
	@return			The number of characters in aBuffer after the integer.
sl@0
   342
	@leave			KUriUtilsErrMalformedInteger if the value in aBuffer is not an integer 
sl@0
   343
					(ie, contains non-decimal characters, or is too big to fit in a TInt)
sl@0
   344
*/
sl@0
   345
EXPORT_C TInt InetProtTextUtils::ExtractIntegerValueL(TPtrC8& aBuffer, TInt& aIntVal, TBool aAllowNonWsTerminator)
sl@0
   346
	{
sl@0
   347
	// Anticipate an empty token by default
sl@0
   348
	TPtrC8 data(aBuffer);
sl@0
   349
sl@0
   350
	// Trim out any whitespace to the left the integer and check there's something left!
sl@0
   351
	InetProtTextUtils::RemoveWhiteSpace(data, InetProtTextUtils::ERemoveLeft);
sl@0
   352
	const TInt len = data.Length();
sl@0
   353
	TInt retVal = aBuffer.Length() -  len; // the amount of WS consumed
sl@0
   354
	if (len == 0)
sl@0
   355
		{
sl@0
   356
		// No integer was found - the supplied buffer was all WS!
sl@0
   357
		aIntVal = 0;
sl@0
   358
		retVal = aBuffer.Length();
sl@0
   359
		aBuffer.Set(data);
sl@0
   360
		}
sl@0
   361
	else
sl@0
   362
		{
sl@0
   363
		// Got some data to work with... find out how many digits are present. Assume that the integer
sl@0
   364
		// required is a contiguous set of decimal digits followed by WS or the end of the buffer
sl@0
   365
		TInt numDigits = 0;
sl@0
   366
		TChar ch = KZero; // default most significant digit to zero without affecting the result
sl@0
   367
		TBool done = EFalse;
sl@0
   368
		while (!done)
sl@0
   369
			{
sl@0
   370
			// check for the end of the integer. This depends on what is allowed to terminate it.
sl@0
   371
			if (aAllowNonWsTerminator)
sl@0
   372
				{
sl@0
   373
				done = (numDigits == data.Length());
sl@0
   374
				if (!done)
sl@0
   375
					{
sl@0
   376
					ch = data[numDigits];
sl@0
   377
					done = ((ch < KZero) || (ch > KNine));
sl@0
   378
					}
sl@0
   379
				}
sl@0
   380
			else
sl@0
   381
				{
sl@0
   382
				done = (numDigits == data.Length());
sl@0
   383
				if (!done)
sl@0
   384
					{
sl@0
   385
					ch = data[numDigits];
sl@0
   386
					done = ((ch == KSpace) || (ch == KHorizTab) || (ch == KDecimal));
sl@0
   387
					}
sl@0
   388
				}
sl@0
   389
sl@0
   390
			// Check that we're getting digits
sl@0
   391
			if (!done)
sl@0
   392
				{
sl@0
   393
				if ((ch < KZero) || (ch > KNine)) // digits 0-9
sl@0
   394
					User::Leave(KUriUtilsErrMalformedInteger);
sl@0
   395
				++numDigits;
sl@0
   396
				}
sl@0
   397
			}
sl@0
   398
		// Make sure there's no overflow (trivial check)
sl@0
   399
		if(numDigits>KMaxTIntDecimalDigits)
sl@0
   400
			User::Leave(KUriUtilsErrMalformedInteger);
sl@0
   401
		
sl@0
   402
		// Now work back, building up the integer
sl@0
   403
		aIntVal = 0;
sl@0
   404
		for (TInt pos = 0; pos < numDigits; pos++)
sl@0
   405
			{
sl@0
   406
			// double check no overflow (
sl@0
   407
			if(aIntVal>KMaxTIntDividedByTen   ||  //works except for 2147483648 and ...49)
sl@0
   408
				( (aIntVal == KMaxTIntDividedByTen)  && (data[pos] >= (KNine-1)) ) // covers those two cases
sl@0
   409
				)  
sl@0
   410
				User::Leave(KUriUtilsErrMalformedInteger);
sl@0
   411
			aIntVal = (data[pos] - KZero) + (aIntVal * 10); // decimal, innit?
sl@0
   412
			}
sl@0
   413
sl@0
   414
		// work out how much this has consumed
sl@0
   415
		retVal += numDigits;
sl@0
   416
sl@0
   417
		// Finally ensure the buffer has had the correct amount of data consumed
sl@0
   418
		if (len == aBuffer.Length())
sl@0
   419
			aBuffer.Set(KNullDesC8()); // there was nothing to the right of the integer
sl@0
   420
		else
sl@0
   421
			aBuffer.Set(aBuffer.Mid(retVal));
sl@0
   422
		}
sl@0
   423
	return retVal;
sl@0
   424
	}
sl@0
   425
sl@0
   426
/*
sl@0
   427
 *	Local methods
sl@0
   428
 */
sl@0
   429
sl@0
   430
/**
sl@0
   431
	@internalComponent
sl@0
   432
	
sl@0
   433
	Does the whitespace removal. Checks the mode and then calls the appropriate
sl@0
   434
	functions.
sl@0
   435
sl@0
   436
	@warning		Will panic will KUriUtilsErrBadTExtRemoveMode if aMode not valid.
sl@0
   437
	@param			aData	A descriptor pointer with the data.
sl@0
   438
	@param			aMode	The specified removal mode.
sl@0
   439
	@return			The number of consumed whitespace characters. If the data is
sl@0
   440
					empty or the data is all whitespace the error code 
sl@0
   441
					KUriUtilsErrEmptyData is returned.
sl@0
   442
*/
sl@0
   443
template<class TPtrCType>
sl@0
   444
TInt DoRemoveWhiteSpace(TPtrCType& aData, InetProtTextUtils::TRemoveMode aMode)
sl@0
   445
	{
sl@0
   446
	TInt consumed = 0;
sl@0
   447
	switch( aMode )
sl@0
   448
		{
sl@0
   449
	case InetProtTextUtils::ERemoveLeft:
sl@0
   450
		{
sl@0
   451
		consumed = FindWhiteSpaceLeft(aData);
sl@0
   452
		if( consumed > 0 )
sl@0
   453
			{
sl@0
   454
			// Found some whitespace
sl@0
   455
			aData.Set(aData.Mid(consumed));
sl@0
   456
			}
sl@0
   457
		} break;
sl@0
   458
	case InetProtTextUtils::ERemoveRight:
sl@0
   459
		{
sl@0
   460
		consumed = FindWhiteSpaceRight(aData);
sl@0
   461
		if( consumed > 0 )
sl@0
   462
			{
sl@0
   463
			// Found some whitespace
sl@0
   464
			aData.Set(aData.Left(aData.Length() - consumed));
sl@0
   465
			}
sl@0
   466
		} break;
sl@0
   467
	case InetProtTextUtils::ERemoveBoth:
sl@0
   468
		{
sl@0
   469
		// Remove from left first...
sl@0
   470
		consumed = FindWhiteSpaceLeft(aData);
sl@0
   471
 		if( consumed != KUriUtilsErrEmptyData )
sl@0
   472
			{
sl@0
   473
			// Found some whitespace - set the pointer then remove from right
sl@0
   474
			aData.Set(aData.Mid(consumed));
sl@0
   475
			TInt consumedRight = FindWhiteSpaceRight(aData);
sl@0
   476
sl@0
   477
			// To get this far descriptor is non-empty and not all whitespace - no check
sl@0
   478
			aData.Set(aData.Left(aData.Length() - consumedRight));
sl@0
   479
			consumed += consumedRight;
sl@0
   480
			}
sl@0
   481
		} break;
sl@0
   482
	default:
sl@0
   483
		__ASSERT_DEBUG(EFalse, User::Panic(KTextUtilsPanicCategory, KUriUtilsErrBadTextRemoveMode));
sl@0
   484
		}
sl@0
   485
	return consumed;
sl@0
   486
	}
sl@0
   487
sl@0
   488
/**
sl@0
   489
	@internalComponent
sl@0
   490
	
sl@0
   491
	Finds the number of contiguous whitespace characters at the 
sl@0
   492
	beginning of the data.
sl@0
   493
sl@0
   494
	@param			aData	A descriptor pointer with the data.
sl@0
   495
	@return			The number of consumed whitespace characters. If the data is
sl@0
   496
					empty or the data is all whitespace the error code 
sl@0
   497
					KTextUtilsErrEmptyData is returned.
sl@0
   498
 */
sl@0
   499
template<class TPtrCType>
sl@0
   500
TInt FindWhiteSpaceLeft(const TPtrCType& aData)
sl@0
   501
	{
sl@0
   502
	const TInt length = aData.Length();
sl@0
   503
	if( length == 0 )
sl@0
   504
		return KUriUtilsErrEmptyData;
sl@0
   505
	TInt i = 0;
sl@0
   506
	TBool done = EFalse;
sl@0
   507
	while( !done && i < length )
sl@0
   508
		{
sl@0
   509
		TChar current = aData[i];
sl@0
   510
		done  = !current.IsSpace();
sl@0
   511
		if( !done )
sl@0
   512
			++i;
sl@0
   513
		}
sl@0
   514
	if( i == length )
sl@0
   515
		return KUriUtilsErrEmptyData;
sl@0
   516
	return i;
sl@0
   517
	}
sl@0
   518
sl@0
   519
/**
sl@0
   520
	@internalComponent
sl@0
   521
	
sl@0
   522
	Finds the number of contiguous whitespace characters at the end of the data.
sl@0
   523
sl@0
   524
	@param			aData	A descriptor pointer with the data.
sl@0
   525
	@return			The number of consumed whitespace characters. If the data is
sl@0
   526
					empty or the data is all whitespace the error code 
sl@0
   527
					KTextUtilsErrEmptyData is returned.
sl@0
   528
*/
sl@0
   529
template<class TPtrCType>
sl@0
   530
TInt FindWhiteSpaceRight(const TPtrCType& aData)
sl@0
   531
	{
sl@0
   532
	const TInt length = aData.Length();
sl@0
   533
	if( length == 0 )
sl@0
   534
		return KUriUtilsErrEmptyData;
sl@0
   535
	TInt i = 0;
sl@0
   536
	TBool done = EFalse;
sl@0
   537
	while( !done && i < length )
sl@0
   538
		{
sl@0
   539
		TChar current = aData[(length-1) - i];
sl@0
   540
		done  = !current.IsSpace();
sl@0
   541
		if( !done )
sl@0
   542
			++i;
sl@0
   543
		}
sl@0
   544
	if( i == length )
sl@0
   545
		return KUriUtilsErrEmptyData;
sl@0
   546
	return i;
sl@0
   547
	}
sl@0
   548
sl@0
   549
/** 
sl@0
   550
	Extracts next token from the buffer.
sl@0
   551
	
sl@0
   552
	@param			aBuffer		The buffer containing the token-list.
sl@0
   553
	@param			aToken		An output argument containing the extracted token.
sl@0
   554
	@param			aSeparator	The separator character.
sl@0
   555
	@return			The number of characters consumed from the buffer.
sl@0
   556
*/
sl@0
   557
template<class TPtrCType>
sl@0
   558
TInt DoExtractNextTokenFromList(TPtrCType& aBuffer, TPtrCType& aToken, TChar aSeparator)
sl@0
   559
	{
sl@0
   560
	// Anticipate an empty token by default.
sl@0
   561
	TInt consumed = 0;
sl@0
   562
sl@0
   563
	// Search for the separator
sl@0
   564
	const TInt pos = aBuffer.Locate(aSeparator);
sl@0
   565
sl@0
   566
	// If the separator was found, take chars upto it. Otherwise use the whole
sl@0
   567
	// remaining buffer - implies the last token in the list.
sl@0
   568
	if( pos == KErrNotFound )
sl@0
   569
		{
sl@0
   570
		// Last token - take the whole lot
sl@0
   571
		aToken.Set(aBuffer);
sl@0
   572
		consumed = aBuffer.Length();
sl@0
   573
		}
sl@0
   574
	else
sl@0
   575
		{
sl@0
   576
		// Take upto the separator position for the token, and move the buffer 
sl@0
   577
		// past the token.
sl@0
   578
		aToken.Set(aBuffer.Left(pos));
sl@0
   579
		consumed = pos + 1;	// include the separator
sl@0
   580
		}
sl@0
   581
	// Set the buffer to move past the extracted token.
sl@0
   582
	aBuffer.Set(aBuffer.Mid(consumed));
sl@0
   583
sl@0
   584
	// Trim out any whitespace surrounding the token, and return how many charas
sl@0
   585
	// were consumed.
sl@0
   586
	InetProtTextUtils::RemoveWhiteSpace(aToken, InetProtTextUtils::ERemoveBoth);
sl@0
   587
	return consumed;
sl@0
   588
	}
sl@0
   589
sl@0
   590
/** 
sl@0
   591
	Extracts next token from the buffer.
sl@0
   592
	
sl@0
   593
	@param			aBuffer		The buffer containing the token-list.
sl@0
   594
	@param			aToken		An output argument containing the extracted token.
sl@0
   595
	@param			aSeparator	The separator.
sl@0
   596
	@return			The number of characters consumed from the buffer.
sl@0
   597
*/
sl@0
   598
template<class TPtrCType>
sl@0
   599
TInt DoExtractNextTokenFromList(TPtrCType& aBuffer, TPtrCType& aToken, const TPtrCType& aSeparator)
sl@0
   600
	{
sl@0
   601
	// Finds the next token in the list, where all the characters in
sl@0
   602
	// the separator array are considered to be separators.
sl@0
   603
sl@0
   604
	// Anticipate an empty token by default.
sl@0
   605
	TInt consumed = 0;
sl@0
   606
sl@0
   607
	// Search for separator...
sl@0
   608
	const TInt length = aBuffer.Length();
sl@0
   609
	TInt pos = 0;
sl@0
   610
	TBool found = EFalse;
sl@0
   611
	while( !found && pos < length )
sl@0
   612
		{
sl@0
   613
		// If we find a quoted string, skip over it (and any token
sl@0
   614
		// separators within it)
sl@0
   615
		if( aBuffer[pos] == KQuote )
sl@0
   616
			{
sl@0
   617
			for( ++pos; pos < length && aBuffer[pos] != KQuote; ++pos )
sl@0
   618
				{}
sl@0
   619
			if (pos == length)
sl@0
   620
				break; // end of string reached
sl@0
   621
			}
sl@0
   622
		if( aSeparator.Locate(aBuffer[pos]) != KErrNotFound )
sl@0
   623
			found = ETrue;
sl@0
   624
		else
sl@0
   625
			++pos;
sl@0
   626
		}
sl@0
   627
sl@0
   628
	// If the separator was found, take chars upto it. Otherwise use the whole
sl@0
   629
	// remaining buffer - implies the last token in the list.
sl@0
   630
	if( found )
sl@0
   631
		{
sl@0
   632
		// Take upto the separator position for the token, and move the buffer 
sl@0
   633
		// past the token.
sl@0
   634
		aToken.Set(aBuffer.Left(pos));
sl@0
   635
		consumed = pos + 1;
sl@0
   636
		}
sl@0
   637
	else
sl@0
   638
		{
sl@0
   639
		// Last token - take the whole lot
sl@0
   640
		aToken.Set(aBuffer);
sl@0
   641
		consumed = aBuffer.Length();
sl@0
   642
		}
sl@0
   643
	// Set the buffer to move past the extracted token.
sl@0
   644
	aBuffer.Set(aBuffer.Mid(consumed));
sl@0
   645
sl@0
   646
	// Trim out any whitespace surrounding the token, and return how
sl@0
   647
	// many characters were extracted.
sl@0
   648
	InetProtTextUtils::RemoveWhiteSpace(aToken, InetProtTextUtils::ERemoveBoth);
sl@0
   649
	return consumed;
sl@0
   650
	}
sl@0
   651
sl@0
   652
/**	
sl@0
   653
	Extract a quoted string value from the buffer. 
sl@0
   654
	
sl@0
   655
	@param			aBuffer			The buffer containing the quoted.
sl@0
   656
	@param			aQuotedString	An output argument containing the extracted
sl@0
   657
									string.
sl@0
   658
	@return			The number of characters consumed from the buffer.
sl@0
   659
*/
sl@0
   660
template<class TPtrCType>
sl@0
   661
TInt DoExtractQuotedStringL(TPtrCType& aBuffer, TPtrCType& aQuotedString)
sl@0
   662
	{
sl@0
   663
	// Find the opening "
sl@0
   664
	TInt quotePos1 = aBuffer.Locate(KQuote);
sl@0
   665
	if( quotePos1 == KErrNotFound )
sl@0
   666
		User::Leave(KUriUtilsErrDecodeMalformedQuotedString);
sl@0
   667
sl@0
   668
	// Find the closing "
sl@0
   669
	TPtrCType temp = aBuffer.Mid(quotePos1 + 1);	// ignore the "
sl@0
   670
	TInt quotePos2 = temp.LocateReverse(KQuote);
sl@0
   671
	if( quotePos2 == KErrNotFound )
sl@0
   672
		User::Leave(KUriUtilsErrDecodeMalformedQuotedString);
sl@0
   673
	
sl@0
   674
	// return what's between them and consume the right number of characters from the buffer
sl@0
   675
	aQuotedString.Set(temp.Left(quotePos2));
sl@0
   676
	TInt consumed = quotePos1 + quotePos2 + 2; // +2 is to consume the quotes themselves
sl@0
   677
	aBuffer.Set(aBuffer.Mid(consumed));
sl@0
   678
	return consumed;
sl@0
   679
	}
sl@0
   680
sl@0
   681
/**
sl@0
   682
	Converts an integer value into its decimal character representation.
sl@0
   683
	
sl@0
   684
	@param			aInt		An integer value.	
sl@0
   685
	@param			aBuffer		An output argument of a pointer to a data buffer
sl@0
   686
	that will contain the character representation of the integer value.
sl@0
   687
	@param			aRadix		enum value.	
sl@0
   688
*/
sl@0
   689
template<class HBufCType>
sl@0
   690
void DoConvertIntToDescriptorL(TInt aInt, HBufCType*& aBuffer, TRadix aRadix)
sl@0
   691
	{
sl@0
   692
	// Create the buffer - max possible size for binary number is 32
sl@0
   693
	TBuf8<KMaxNumberSize> buf;
sl@0
   694
	buf.SetMax();
sl@0
   695
sl@0
   696
	// Is the number -ve?
sl@0
   697
	TUint value = aInt;
sl@0
   698
	TBool negative = EFalse;
sl@0
   699
	if( aInt < 0 )
sl@0
   700
		{
sl@0
   701
		negative = ETrue;
sl@0
   702
		value = -aInt;
sl@0
   703
		}
sl@0
   704
sl@0
   705
	// Now form the number...
sl@0
   706
	TInt index = KMaxNumberSize;
sl@0
   707
	do	
sl@0
   708
		{
sl@0
   709
		// Update the index
sl@0
   710
		--index;
sl@0
   711
		__ASSERT_DEBUG( index > 0, User::Invariant() );
sl@0
   712
sl@0
   713
		// Find the value of the least significant digit
sl@0
   714
		TUint q = value/aRadix;
sl@0
   715
		TUint c = value - (q*aRadix);
sl@0
   716
sl@0
   717
		// Convert digit to character and insert into the buffer.
sl@0
   718
		( c > 9 ) ? c += (KAChar-10) : c += KZeroChar;
sl@0
   719
		buf[index] = STATIC_CAST(TUint8, c);
sl@0
   720
sl@0
   721
		// Update the value left to convert.
sl@0
   722
		value = q;
sl@0
   723
		} while( value > 0 );
sl@0
   724
sl@0
   725
	// Add the '-' sign if number was negative
sl@0
   726
	if( negative )
sl@0
   727
		buf[--index] = KMinusSign;
sl@0
   728
sl@0
   729
	// Create the output buffer...
sl@0
   730
	TPtrC8 number = buf.Mid(index);
sl@0
   731
	aBuffer = HBufCType::NewL(number.Length());
sl@0
   732
	aBuffer->Des().Copy(number);
sl@0
   733
	}
sl@0
   734
sl@0
   735
/**
sl@0
   736
	Converts the character representation of an integer into its numeric value.
sl@0
   737
	Preceeding whitespace is ignored and the integer is delimited by either the
sl@0
   738
	end of the data, whitespace or any other character other than 0 to 9.
sl@0
   739
	
sl@0
   740
	@param			aData	A descriptor pointer with the data.
sl@0
   741
	@param			aInt	An output argument in which the numeric value of the
sl@0
   742
	data is placed.
sl@0
   743
	@param			aRadix		enum value.	
sl@0
   744
	@return			The number of consumed characters that contributed to the 
sl@0
   745
					integer value, including any whitespace before the integer. 
sl@0
   746
					If the data is empty the error code KUriUtilsErrEmptyData 
sl@0
   747
					is returned. If there are no digits at the beginning of the
sl@0
   748
					data the error code KUriUtilsErrNoIntergerInData is returned.
sl@0
   749
*/
sl@0
   750
template<class TPtrCType>
sl@0
   751
TInt DoConvertDescriptorToInt(const TPtrCType& aData, TInt& aInt, TRadix aRadix)
sl@0
   752
	{
sl@0
   753
	// Remove any whitespace before the digits
sl@0
   754
	TPtrCType data = aData;
sl@0
   755
	TInt consumed = InetProtTextUtils::RemoveWhiteSpace(data, InetProtTextUtils::ERemoveLeft);
sl@0
   756
sl@0
   757
	// Ensure that there are some digits to convert
sl@0
   758
	TInt length = data.Length();
sl@0
   759
	if( length == 0 )
sl@0
   760
		{
sl@0
   761
		return KUriUtilsErrEmptyData;
sl@0
   762
		}
sl@0
   763
sl@0
   764
	// Search for digits and calculate value - stop when non-digit found
sl@0
   765
	TInt value = 0;
sl@0
   766
	TBool done = EFalse;
sl@0
   767
	
sl@0
   768
	TBool negative=EFalse;
sl@0
   769
sl@0
   770
	if(data[0]==KMinusSign)
sl@0
   771
	   {
sl@0
   772
		negative=ETrue;
sl@0
   773
	   }	
sl@0
   774
	
sl@0
   775
	TInt i=0;
sl@0
   776
	
sl@0
   777
	// Length is verifying as user input may be just only '-' sign.
sl@0
   778
	if( negative && length > 1 )
sl@0
   779
		{
sl@0
   780
		i = 1;	
sl@0
   781
		}
sl@0
   782
	while( !done )
sl@0
   783
		{
sl@0
   784
		// Get the current char and see if it is a digit
sl@0
   785
		TChar c = data[i];
sl@0
   786
sl@0
   787
		if( c.IsHexDigit() )
sl@0
   788
			{
sl@0
   789
			// Need to convert char to its numeric value
sl@0
   790
			TInt digit = c - KZeroChar;
sl@0
   791
sl@0
   792
			// Was the char in the A-F range?
sl@0
   793
			if( digit > 9 )
sl@0
   794
				digit = c.GetUpperCase() - (KAChar - 10);
sl@0
   795
			
sl@0
   796
			if( digit > aRadix )
sl@0
   797
				{
sl@0
   798
				// The character is too large for the radix - end of data.
sl@0
   799
				done = ETrue;
sl@0
   800
				}
sl@0
   801
			else
sl@0
   802
				{
sl@0
   803
				// Update running total
sl@0
   804
				value *= aRadix;
sl@0
   805
				value += digit;
sl@0
   806
				}
sl@0
   807
			}
sl@0
   808
		else
sl@0
   809
			{
sl@0
   810
			// Non-digit found - we're done!
sl@0
   811
			done = ETrue;
sl@0
   812
			}
sl@0
   813
		// Check for end of data
sl@0
   814
		done = done || !(++i < length);
sl@0
   815
		}
sl@0
   816
	// Set up outputs
sl@0
   817
	if( i == 0 )
sl@0
   818
		{
sl@0
   819
		// No digits found in data - do not set aInt
sl@0
   820
		return KUriUtilsErrNoIntegerInData;
sl@0
   821
		}
sl@0
   822
	// Set the value of the interger
sl@0
   823
	if( negative )
sl@0
   824
		aInt = -value;
sl@0
   825
	else
sl@0
   826
		aInt = value;
sl@0
   827
sl@0
   828
	// Return consumed characters
sl@0
   829
	return i + consumed;
sl@0
   830
	}