os/ossrv/genericservices/httputils/UriParser/TUriParser.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
// System includes
sl@0
    17
#include <uri8.h>
sl@0
    18
#include <uri16.h>
sl@0
    19
#include <uriutils.h>
sl@0
    20
#include <uriutilscommon.h>
sl@0
    21
sl@0
    22
sl@0
    23
//User includes
sl@0
    24
#include "TUriParserInternal.h"
sl@0
    25
#include "UriUtilsInternal.h"
sl@0
    26
#include "TUriCInternal.h"
sl@0
    27
#include "GenericUriParser.h"
sl@0
    28
#include "SipUriParser.h"
sl@0
    29
sl@0
    30
sl@0
    31
sl@0
    32
// Constants
sl@0
    33
//
sl@0
    34
sl@0
    35
_LIT8(KSIP, "Sip");
sl@0
    36
_LIT8(KSIPS, "Sips");
sl@0
    37
sl@0
    38
sl@0
    39
//
sl@0
    40
//
sl@0
    41
// Implementation of TUriParser8
sl@0
    42
//
sl@0
    43
//
sl@0
    44
sl@0
    45
/**
sl@0
    46
	Constructor.
sl@0
    47
	
sl@0
    48
	@since			6.0
sl@0
    49
 */
sl@0
    50
EXPORT_C TUriParser8::TUriParser8()
sl@0
    51
: TUriC8()
sl@0
    52
	{
sl@0
    53
	}
sl@0
    54
	
sl@0
    55
/**
sl@0
    56
	Parses the descriptor aUri into uri components.
sl@0
    57
	
sl@0
    58
	@since			6.0
sl@0
    59
	@param			aUri A reference to a descriptor pointer to be parsed.
sl@0
    60
	@return			KErrNone if the descriptor has been parsed into uri components.
sl@0
    61
	KUriUtilsParserErrInvalidUri if the descriptor is an invalid uri.
sl@0
    62
	KErrNoMemory if out of memory
sl@0
    63
	@post			The object references the input descriptor.
sl@0
    64
 */
sl@0
    65
EXPORT_C TInt TUriParser8::Parse(const TDesC8& aUri)
sl@0
    66
	{
sl@0
    67
	// Reset the Uri information and then set the Uri
sl@0
    68
	if( iUriDes.Length() )
sl@0
    69
		{
sl@0
    70
		Reset();
sl@0
    71
		}
sl@0
    72
	iUriDes.Set(aUri);
sl@0
    73
sl@0
    74
	// Check uri is valid
sl@0
    75
	if( iUriDes.Length() && iUriDes[0]==KSchemeDelimiter )
sl@0
    76
		{
sl@0
    77
		return KUriUtilsErrInvalidUri;
sl@0
    78
		}
sl@0
    79
	
sl@0
    80
	TPtrC8 schemeComponent;
sl@0
    81
	RetrieveScheme(iUriDes,schemeComponent);
sl@0
    82
	CGenericUriParser* UriHandler = NULL;
sl@0
    83
	TInt err=KErrNone;
sl@0
    84
	if(schemeComponent.CompareF(KSIP()) == 0 || schemeComponent.CompareF(KSIPS()) == 0 )
sl@0
    85
		{
sl@0
    86
	    TRAP(err,UriHandler = CSIPUriParser::NewL());
sl@0
    87
		}
sl@0
    88
	else
sl@0
    89
		{
sl@0
    90
	    TRAP(err,UriHandler = CGenericUriParser::NewL());
sl@0
    91
 		}
sl@0
    92
	if(UriHandler)
sl@0
    93
		{
sl@0
    94
		UriHandler->DoParseUri(iUriDes, iComponent);
sl@0
    95
		delete UriHandler;
sl@0
    96
		}
sl@0
    97
       
sl@0
    98
		return err;      
sl@0
    99
sl@0
   100
	}
sl@0
   101
sl@0
   102
/**
sl@0
   103
	Parses the descriptor aUri into uri components.
sl@0
   104
	
sl@0
   105
	@param			aUri A reference to a descriptor pointer of an Uri.
sl@0
   106
	@param			aScheme A reference to a descriptor pointer for retieved 
sl@0
   107
					scheme component.
sl@0
   108
 */
sl@0
   109
void TUriParser8::RetrieveScheme(const TPtrC8& aUri, TPtrC8& aScheme)
sl@0
   110
	{
sl@0
   111
	TInt schemePos = aUri.Locate(KSchemeDelimiter);
sl@0
   112
	if(schemePos != KErrNotFound)
sl@0
   113
		{
sl@0
   114
		// Got a scheme - store information
sl@0
   115
		aScheme.Set(aUri.Left(schemePos));
sl@0
   116
		}
sl@0
   117
	}
sl@0
   118
sl@0
   119
//
sl@0
   120
//
sl@0
   121
// Implementation of TUriParser16
sl@0
   122
//
sl@0
   123
//
sl@0
   124
sl@0
   125
/**
sl@0
   126
	Constructor.
sl@0
   127
	
sl@0
   128
	@since			6.0
sl@0
   129
	@deprecated Deprecated in 9.1
sl@0
   130
 */
sl@0
   131
EXPORT_C TUriParser16::TUriParser16()
sl@0
   132
: TUriC16()
sl@0
   133
	{
sl@0
   134
	}
sl@0
   135
sl@0
   136
/**
sl@0
   137
	Parses the descriptor aUri into uri components.
sl@0
   138
	
sl@0
   139
	@since			6.0
sl@0
   140
	@deprecated Deprecated in 9.1
sl@0
   141
	@param			aUri A reference to a descriptor pointer to be parsed.
sl@0
   142
	@return			KErrNone if the descriptor has been parsed into uri components.
sl@0
   143
	EUriParserErrInvalidUri if the descriptor is an invalid uri.
sl@0
   144
	@post			The object references the input descriptor.
sl@0
   145
 */
sl@0
   146
EXPORT_C TInt TUriParser16::Parse(const TDesC16& aUri)
sl@0
   147
	{
sl@0
   148
	// Reset the Uri information and then set the Uri
sl@0
   149
	if( iUriDes.Length() )
sl@0
   150
		Reset();
sl@0
   151
	iUriDes.Set(aUri);
sl@0
   152
sl@0
   153
	// Check uri is valid
sl@0
   154
	if( iUriDes.Length() && iUriDes[0]==KSchemeDelimiter )
sl@0
   155
		return KUriUtilsErrInvalidUri;
sl@0
   156
sl@0
   157
	// Parse the uri.
sl@0
   158
	DoParseUri(iUriDes, iComponent);
sl@0
   159
	return KErrNone;
sl@0
   160
	}
sl@0
   161
sl@0
   162
//
sl@0
   163
//
sl@0
   164
// Implementation of templated LOCAL functions
sl@0
   165
//
sl@0
   166
//
sl@0
   167
sl@0
   168
/**
sl@0
   169
	Templated function that parses a descriptor into the components of a uri.
sl@0
   170
						
sl@0
   171
	@since			6.0
sl@0
   172
	@param			aUri		The descriptor with the data to parse.
sl@0
   173
	@param			aComponent	The output array of descriptors of each uri component.
sl@0
   174
	@pre 			Each descriptor pointer in aComponent has had the pointer to its
sl@0
   175
					associated descriptor buffer set to NULL.
sl@0
   176
	@post			The descriptor pointers in aComponent are updated to refer to the 
sl@0
   177
					appropriate sections of aUri that represent the components of a uri.
sl@0
   178
*/
sl@0
   179
template<class TPtrCType>
sl@0
   180
void DoParseUri(const TPtrCType& aUri, TPtrCType aComponent[])
sl@0
   181
	{
sl@0
   182
	// Parse the components
sl@0
   183
	TPtrCType uri = aUri;
sl@0
   184
	TInt consumed = 0;
sl@0
   185
	TPtrCType& scheme = aComponent[EUriScheme];
sl@0
   186
	if( (consumed = ParseScheme(uri, scheme)) > 0 )
sl@0
   187
		{
sl@0
   188
		uri.Set(uri.Mid(consumed));
sl@0
   189
		}
sl@0
   190
	if( (consumed = ParseAuthority(uri, aComponent[EUriUserinfo], 
sl@0
   191
		 aComponent[EUriHost], aComponent[EUriPort], IsNetworkScheme(scheme))) > 0 )
sl@0
   192
		{
sl@0
   193
		uri.Set(uri.Mid(consumed));
sl@0
   194
		}
sl@0
   195
	if( (consumed = ParsePath(uri, aComponent[EUriPath])) > 0 )
sl@0
   196
		{
sl@0
   197
		uri.Set(uri.Mid(consumed));
sl@0
   198
		}
sl@0
   199
	if( (consumed = ParseQuery(uri, aComponent[EUriQuery])) > 0 )
sl@0
   200
		{
sl@0
   201
		uri.Set(uri.Mid(consumed));
sl@0
   202
		}
sl@0
   203
	if( (consumed = ParseFragment(uri, aComponent[EUriFragment])) > 0 )
sl@0
   204
		{
sl@0
   205
		uri.Set(uri.Mid(consumed));
sl@0
   206
		}
sl@0
   207
	}
sl@0
   208
sl@0
   209
/**
sl@0
   210
	Templated function to parse a descriptor for a scheme component. If a scheme is found 
sl@0
   211
	then the output argument aScheme is set to refer to it.
sl@0
   212
						
sl@0
   213
	@since			6.0
sl@0
   214
	@param			aUri	The descriptor containing the uri to be parsed for 
sl@0
   215
	a scheme.
sl@0
   216
	@param			aScheme	The output descriptor to refer to the scheme
sl@0
   217
	@return			The number of characters consumed in parsing the scheme.
sl@0
   218
	@pre 			The output descriptor has been initialized so that the pointer
sl@0
   219
					to the associated descriptor buffer is NULL. The input descriptor 
sl@0
   220
					is set to the start of the uri.
sl@0
   221
	@post			If a scheme component exists then the output descriptor refers
sl@0
   222
					to it, otherwise the output descriptor is left unchanged.
sl@0
   223
*/
sl@0
   224
template<class TPtrCType>
sl@0
   225
TInt ParseScheme(const TPtrCType& aUri, TPtrCType& aScheme)
sl@0
   226
	{
sl@0
   227
	// Get the descriptor and look for scheme delimiter
sl@0
   228
	TInt consumed =0;
sl@0
   229
	TInt endSchemePos = FindFirstUriDelimiter(aUri, ESchemeDelimiterSearch);
sl@0
   230
sl@0
   231
	if( endSchemePos != KErrNotFound )
sl@0
   232
		{
sl@0
   233
		// Got a scheme - store information
sl@0
   234
		aScheme.Set(aUri.Left(endSchemePos));
sl@0
   235
sl@0
   236
		// Set consumed amount move past scheme delimiter
sl@0
   237
		consumed = endSchemePos + 1;
sl@0
   238
		}
sl@0
   239
	return consumed;
sl@0
   240
	}
sl@0
   241
	
sl@0
   242
/**
sl@0
   243
	Templated function to parse a descriptor for an authority component. If an authority is 
sl@0
   244
	found then the output arguments aUserinfo, aHost and aPort are set to refer to those parts 
sl@0
   245
	of the authority component. If an authority component exists then the host part exists. The 
sl@0
   246
	userinfo and port parts are optional.
sl@0
   247
						
sl@0
   248
	@since			6.0
sl@0
   249
	@param			aUri		The descriptor containing the uri to be parsed 
sl@0
   250
					for an authority.
sl@0
   251
	@param			aUserinfo	The output descriptor for the userinfo component.
sl@0
   252
	@param			aHost		The output descriptor for the host component.
sl@0
   253
	@param			aPort		The output descriptor for the port component.
sl@0
   254
	@param			aUseNetworkDelimiter Whether the scheme uses the network delimeter '//'
sl@0
   255
	@return			The number of characters consumed in parsing the authority.
sl@0
   256
	@pre 			The output descriptors have been initialized so that the pointer
sl@0
   257
					to the their associated descriptor buffers is NULL. The input descriptor 
sl@0
   258
					is set to the start of the start of the authority component.
sl@0
   259
	
sl@0
   260
	@post			If an authority component exists then the output descriptors refer
sl@0
   261
					to the userinfo part (if exists), the host part and the port part (if exists), 
sl@0
   262
					otherwise the output descriptors are left unchanged.
sl@0
   263
*/
sl@0
   264
sl@0
   265
template<class TPtrCType> 
sl@0
   266
TInt ParseAuthority(const TPtrCType& aUri, TPtrCType& aUserinfo, TPtrCType& aHost, TPtrCType& aPort, TBool aUseNetworkDelimiter)
sl@0
   267
	{
sl@0
   268
	// Get uri descriptor and see if authority exists - if aUseNetworkDelimiter is true it has to start with '//' 
sl@0
   269
	TInt consumed =0;
sl@0
   270
	const TInt prefixLength = aUseNetworkDelimiter ? KUriNetworkAuthorityDelimiterLength : 0;
sl@0
   271
  	if( !aUseNetworkDelimiter || 
sl@0
   272
  		(aUri.Length() >= prefixLength && aUri[0] == KSlashDelimiter && aUri[1] == KSlashDelimiter ))
sl@0
   273
		{
sl@0
   274
		// There is an authority
sl@0
   275
		TPtrCType authority = aUri.Mid(prefixLength);
sl@0
   276
sl@0
   277
		// Authority delimited by '/', '?', '#' or the end of the string
sl@0
   278
		TInt authorityEndPos = FindFirstUriDelimiter(authority, EAuthDelimiterSearch);
sl@0
   279
sl@0
   280
		// Got authority - parse it for its components
sl@0
   281
		authority.Set(authority.Left(authorityEndPos));
sl@0
   282
sl@0
   283
		// Get the userinfo...
sl@0
   284
		TInt userinfoEndPos = authority.Locate(KUserinfoDelimiter);
sl@0
   285
		if( userinfoEndPos != KErrNotFound )
sl@0
   286
			{
sl@0
   287
			// Store the information 
sl@0
   288
			aUserinfo.Set(authority.Left(userinfoEndPos));
sl@0
   289
			  
sl@0
   290
			// Move past the userinfo and the delimiter '@'
sl@0
   291
			authority.Set(authority.Mid(userinfoEndPos + 1));
sl@0
   292
			}
sl@0
   293
sl@0
   294
		// Authority is also delimited by ';' but this is valid in the userinfo so can only be checked now
sl@0
   295
		TInt semicolonPos = FindFirstUriDelimiter(authority, ESemiColonDelimiterFlag);
sl@0
   296
		if ( semicolonPos != KErrNotFound )
sl@0
   297
			{
sl@0
   298
			authority.Set(authority.Left(semicolonPos));
sl@0
   299
			authorityEndPos = semicolonPos + userinfoEndPos + 1;
sl@0
   300
			}
sl@0
   301
		
sl@0
   302
		// Set consumed amount to move past authority
sl@0
   303
		consumed += prefixLength + authorityEndPos;
sl@0
   304
		
sl@0
   305
		// Check if this is an IPv6 address	by looking for the opening '['
sl@0
   306
		TInt startHostIPv6 = authority.Locate(KIPv6UriOpenBrace);
sl@0
   307
sl@0
   308
		if (startHostIPv6==KErrNotFound)
sl@0
   309
			{
sl@0
   310
			// This isn't an IPv6 address.....
sl@0
   311
sl@0
   312
			// Get host...
sl@0
   313
			TInt hostEndPos = authority.Locate(KPortDelimiter);
sl@0
   314
sl@0
   315
			// Host also delimited by the end of the authority
sl@0
   316
			if( hostEndPos == KErrNotFound )
sl@0
   317
				hostEndPos = authority.Length();
sl@0
   318
sl@0
   319
			// There's always a host, but can be empty - store information
sl@0
   320
			aHost.Set(authority.Left(hostEndPos));
sl@0
   321
sl@0
   322
			// Move past the host
sl@0
   323
			authority.Set(authority.Mid(hostEndPos));
sl@0
   324
			}
sl@0
   325
		else
sl@0
   326
			{
sl@0
   327
		
sl@0
   328
	    // First, move past the opening brace
sl@0
   329
	        authority.Set(authority.Mid(startHostIPv6 + 1));
sl@0
   330
	            // auth now = X:X:X]?????
sl@0
   331
	            
sl@0
   332
			// This is an IPv6 address, so it MUST have the closing brace too....
sl@0
   333
			TInt endIPv6Host = authority.Locate(KIPv6UriCloseBrace);
sl@0
   334
sl@0
   335
			// Return an error if the closing IPv6 delimiter isn't there.
sl@0
   336
			if (endIPv6Host==KErrNotFound)
sl@0
   337
				return KUriUtilsErrInvalidUri;
sl@0
   338
sl@0
   339
			// It's an ipv6  address, with an opening and closing brace. So now just extract it
sl@0
   340
			// auth = [X:X:X]?????
sl@0
   341
sl@0
   342
sl@0
   343
			// Set the host, and need to remove the closing brace
sl@0
   344
			aHost.Set(authority.Left(endIPv6Host));
sl@0
   345
			// host = X:X:X
sl@0
   346
sl@0
   347
			// Move past the host
sl@0
   348
			authority.Set(authority.Mid(endIPv6Host + 1 ));
sl@0
   349
			}
sl@0
   350
		
sl@0
   351
		// Get the port...
sl@0
   352
		TInt portEndPos = authority.Length();
sl@0
   353
		if( portEndPos )
sl@0
   354
			{
sl@0
   355
			// Store the port - remove leading ':'
sl@0
   356
			aPort.Set(authority.Mid(1, portEndPos - 1));
sl@0
   357
			}
sl@0
   358
		}
sl@0
   359
	return consumed;
sl@0
   360
	}
sl@0
   361
sl@0
   362
/**
sl@0
   363
	Templated function to parse a descriptor for a path component.There is always a path component.
sl@0
   364
	The ouput argument aPath is set to the path component found.
sl@0
   365
						
sl@0
   366
	@since			6.0
sl@0
   367
	@param			aUri	The descriptor containing the uri to be parsed for 
sl@0
   368
	a path.
sl@0
   369
	@param			aComponent	The output descriptor to refer to the path.
sl@0
   370
	@return			The number of characters consumed in parsing the path.
sl@0
   371
	@pre 			The output descriptor has been initialized so that the pointer
sl@0
   372
					to the associated descriptor buffer is NULL. The input descriptor 
sl@0
   373
					is set to the start of the path.
sl@0
   374
					
sl@0
   375
	@post			The output descriptor refers to the path component.
sl@0
   376
*/
sl@0
   377
template<class TPtrCType>
sl@0
   378
TInt ParsePath(const TPtrCType& aUri, TPtrCType& aComponent)
sl@0
   379
	{
sl@0
   380
	// Get descriptor with the path
sl@0
   381
	TInt consumed =0;
sl@0
   382
sl@0
   383
	// Path is delimited by '?'. '#' or the end of the string
sl@0
   384
	TInt pathEndPos = FindFirstUriDelimiter(aUri, EPathDelimiterSearch);
sl@0
   385
sl@0
   386
	// Check for presence of path
sl@0
   387
	if( pathEndPos != KErrNotFound )
sl@0
   388
		{
sl@0
   389
		// Got path - store information
sl@0
   390
		aComponent.Set(aUri.Left(pathEndPos));
sl@0
   391
	
sl@0
   392
		// Set consumed amount to move past path
sl@0
   393
		consumed = pathEndPos;
sl@0
   394
		}
sl@0
   395
	return consumed;
sl@0
   396
	}
sl@0
   397
sl@0
   398
/**
sl@0
   399
	Templated function to parse a descriptor for a query component.If a query is found then 
sl@0
   400
	the output argument aQuery is set to refer to it.
sl@0
   401
						
sl@0
   402
	@since			6.0
sl@0
   403
	@param			aUri	The descriptor containing the uri to be parsed for 
sl@0
   404
	a query.
sl@0
   405
	@param			aComponent	The output descriptor to refer to the query
sl@0
   406
	@return			The number of characters consumed in parsing the query.
sl@0
   407
	@pre 			The output descriptor has been initialized so that the pointer
sl@0
   408
					to the associated descriptor buffer is NULL. The input descriptor is set to
sl@0
   409
					the start of the query.
sl@0
   410
	@post			If a query component exists then the output descriptor refers
sl@0
   411
					to it, otherwise the output descriptor is left unchanged.
sl@0
   412
*/
sl@0
   413
template<class TPtrCType>
sl@0
   414
TInt ParseQuery(const TPtrCType& aUri, TPtrCType& aComponent)
sl@0
   415
	{
sl@0
   416
	// Get descriptor with the query
sl@0
   417
	TInt consumed =0;
sl@0
   418
sl@0
   419
	// Query is delimited by '#' or end of the string 
sl@0
   420
	TInt queryEndPos = FindFirstUriDelimiter(aUri, EQueryDelimiterSearch);
sl@0
   421
sl@0
   422
	// Check for presence of query
sl@0
   423
	if( queryEndPos )
sl@0
   424
		{
sl@0
   425
		// Got query - store information; need to excluded leading '?'
sl@0
   426
		aComponent.Set(aUri.Mid(1, queryEndPos - 1));
sl@0
   427
	
sl@0
   428
		// Set consumed amount to move past query
sl@0
   429
		consumed = queryEndPos;
sl@0
   430
		}
sl@0
   431
	return consumed;
sl@0
   432
	}
sl@0
   433
sl@0
   434
/**
sl@0
   435
	Templated function to parse a descriptor for a fragment component. If a fragment is found then 
sl@0
   436
	the output argument aFragment is set to refer to it.
sl@0
   437
						
sl@0
   438
	@since			6.0
sl@0
   439
	@param			aUri		The descriptor containing the uri to be parsed for 
sl@0
   440
					a fragment.
sl@0
   441
	@param			aComponent	The output descriptor to refer to the fragment.
sl@0
   442
	@return			The number of characters consumed in parsing the fragment.
sl@0
   443
	@pre 			The output descriptor has been initialized so that the pointer
sl@0
   444
					to the associated descriptor buffer is NULL. The input descriptor is set to
sl@0
   445
					the start of the fragment.
sl@0
   446
	@post			If a fragment component exists then the output descriptor refers
sl@0
   447
					to it, otherwise the output descriptor is left unchanged.
sl@0
   448
*/
sl@0
   449
template<class TPtrCType>
sl@0
   450
TInt ParseFragment(const TPtrCType& aUri, TPtrCType& aComponent)
sl@0
   451
	{
sl@0
   452
	// Get descriptor with the fragment
sl@0
   453
	TInt consumed =0;
sl@0
   454
sl@0
   455
	// Fragment is delimited by end of the string
sl@0
   456
	TInt fragmentEndPos = aUri.Length();
sl@0
   457
sl@0
   458
	// Check for presence of fragment
sl@0
   459
	if( fragmentEndPos )
sl@0
   460
		{
sl@0
   461
		// Got fragment - store information; need to excluded leading '#'
sl@0
   462
		aComponent.Set(aUri.Mid(1, fragmentEndPos - 1));
sl@0
   463
	
sl@0
   464
		// Set consumed amount to move past fragment
sl@0
   465
		consumed = fragmentEndPos;
sl@0
   466
		}
sl@0
   467
	return consumed;
sl@0
   468
	}
sl@0
   469
	
sl@0
   470
/**
sl@0
   471
	Templated function to find the position of the first delimiter in the descriptor specified 
sl@0
   472
	by the delimiter flags. Note that the end of the descriptor is also a delimiter if there are 
sl@0
   473
	no others. In the case of the scheme delimiter search, the position returned depends on the 
sl@0
   474
	position of the colon delimiter with respect to the other delimiters for a scheme.
sl@0
   475
						
sl@0
   476
	@since			6.0
sl@0
   477
	@param			aUri		The descriptor containing the section of a uri to be searched.
sl@0
   478
	@param			aSearchFlag	The enum specifying the delimiters to search for.
sl@0
   479
	@return			The position of nearest delimiter to start of the descriptor, where
sl@0
   480
					zero is the start (left-most) position.
sl@0
   481
*/
sl@0
   482
template<class TPtrCType> 
sl@0
   483
TInt FindFirstUriDelimiter(const TPtrCType& aUri, TDelimiterSearchFlag aSearchFlag)
sl@0
   484
	{
sl@0
   485
	// Set ultimate delimiter - string length
sl@0
   486
	TInt endPos = aUri.Length();
sl@0
   487
	if( aSearchFlag & EHashDelimiterFlag )
sl@0
   488
		{
sl@0
   489
		TInt fragmentPos = aUri.Locate(KFragmentDelimiter);
sl@0
   490
		if( fragmentPos != KErrNotFound && fragmentPos < endPos )
sl@0
   491
			endPos = fragmentPos;
sl@0
   492
		}
sl@0
   493
	if( aSearchFlag & EQueryDelimiterFlag )
sl@0
   494
		{
sl@0
   495
		TInt queryPos = aUri.Locate(KQueryDelimiter);
sl@0
   496
		if( queryPos != KErrNotFound && queryPos < endPos )
sl@0
   497
			endPos = queryPos;
sl@0
   498
		}
sl@0
   499
	if( aSearchFlag & ESlashDelimiterFlag )
sl@0
   500
		{
sl@0
   501
		TInt slashPos = aUri.Locate(KSlashDelimiter);
sl@0
   502
		if( slashPos != KErrNotFound && slashPos < endPos )
sl@0
   503
			endPos = slashPos;
sl@0
   504
		}
sl@0
   505
	if( aSearchFlag & ESemiColonDelimiterFlag )
sl@0
   506
		{
sl@0
   507
		TInt semiColonPos = aUri.Locate(KParamDelimiter);
sl@0
   508
		if( semiColonPos != KErrNotFound && semiColonPos < endPos )
sl@0
   509
			endPos = semiColonPos;
sl@0
   510
		}
sl@0
   511
	if( aSearchFlag & EColonDelimiterFlag )
sl@0
   512
		{
sl@0
   513
		TInt schemePos = aUri.Locate(KSchemeDelimiter);
sl@0
   514
		if( schemePos != KErrNotFound && schemePos < endPos )
sl@0
   515
			{
sl@0
   516
			// There is a scheme
sl@0
   517
			endPos = schemePos;
sl@0
   518
			}
sl@0
   519
		else if( aSearchFlag == ESchemeDelimiterSearch )
sl@0
   520
			{
sl@0
   521
			// Ok different if looking for scheme delimiter - no scheme, return KErrNotFound
sl@0
   522
			endPos = KErrNotFound;
sl@0
   523
			}
sl@0
   524
		}
sl@0
   525
	return endPos;
sl@0
   526
	}