genericservices/httputils/UriParser/SipUriParser.cpp
changeset 0 e4d67989cc36
child 27 3a7375419266
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     1 // Copyright (c) 2007-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 #include "SipUriParser.h"
       
    17 
       
    18 /** 
       
    19  * CSIPUriParser Constructor.
       
    20  */ 
       
    21 CSIPUriParser::CSIPUriParser()
       
    22 : CGenericUriParser()
       
    23 	{
       
    24 	}
       
    25 
       
    26 /** 
       
    27  * CSIPUriParser Static Factory Construction.
       
    28  */
       
    29 CSIPUriParser* CSIPUriParser::NewL()
       
    30 	{
       
    31 	CSIPUriParser* self = new (ELeave) CSIPUriParser;
       
    32 	CleanupStack::PushL(self);
       
    33 	self->ConstructL();
       
    34 	CleanupStack::Pop(self);
       
    35 	return self;
       
    36 	}
       
    37 
       
    38 /**	
       
    39 	Second phase of two-phase construction method. 
       
    40 	
       
    41 	@pre 			First phase of construction is complete.
       
    42 	@post			The object is fully constructed and initialized.
       
    43  */
       
    44 void CSIPUriParser::ConstructL()
       
    45 	{
       
    46 	// Does nothing.
       
    47 	}
       
    48 
       
    49 /**
       
    50  * Default Destructor.
       
    51  */
       
    52 CSIPUriParser::~CSIPUriParser()
       
    53 	{
       
    54 	}
       
    55 
       
    56 /**
       
    57 	Function to parse a descriptor for a scheme component. If a scheme is found 
       
    58 	then the output argument aScheme is set to refer to it.
       
    59 						
       
    60 	@param			aUri	The descriptor containing the uri to be parsed for a scheme.
       
    61 	@param			aScheme	The output descriptor to refer to the scheme
       
    62 	@return			The number of characters consumed in parsing the scheme.
       
    63 	@pre 			The output descriptor has been initialized so that the pointer
       
    64 					to the associated descriptor buffer is NULL. The input descriptor 
       
    65 					is set to the start of the uri.
       
    66 	@post			If a scheme component exists then the output descriptor refers
       
    67 					to it, otherwise the output descriptor is left unchanged.
       
    68 */
       
    69 TInt CSIPUriParser::ParseScheme(const TPtrC8& aUri, TPtrC8& aScheme)
       
    70 	{
       
    71 	// Get the descriptor and look for scheme delimiter
       
    72 	TInt consumed =0;
       
    73 	TInt endSchemePos = FindFirstUriDelimiter(aUri, ESipSchemeDelimiterSearch);
       
    74 
       
    75 	if( endSchemePos != KErrNotFound )
       
    76 		{
       
    77 		// Got a scheme - store information
       
    78 		aScheme.Set(aUri.Left(endSchemePos));
       
    79 
       
    80 		// Set consumed amount move past scheme delimiter
       
    81 		consumed = endSchemePos + 1;
       
    82 		}
       
    83 	return consumed;
       
    84 	}
       
    85 	
       
    86 /**
       
    87 	Function to parse a descriptor for an authority component. If an authority is 
       
    88 	found then the output arguments aUserinfo, aHost and aPort are set to refer to those parts 
       
    89 	of the authority component. If an authority component exists then the host part exists. The 
       
    90 	userinfo and port parts are optional.
       
    91 						
       
    92 	@param			aUri		The descriptor containing the uri to be parsed 
       
    93 					for an authority.
       
    94 	@param			aUserinfo	The output descriptor for the userinfo component.
       
    95 	@param			aHost		The output descriptor for the host component.
       
    96 	@param			aPort		The output descriptor for the port component.
       
    97 	@param			aUseNetworkDelimiter is not used as we know the Sip scheme 
       
    98 					not uses the network delimeter '//'
       
    99 	@return			The number of characters consumed in parsing the authority.
       
   100 	@pre 			The output descriptors have been initialized so that the pointer
       
   101 					to the their associated descriptor buffers is NULL. The input descriptor 
       
   102 					is set to the start of the start of the authority component.
       
   103 	
       
   104 	@post			If an authority component exists then the output descriptors refer
       
   105 					to the userinfo part (if exists), the host part and the port part (if exists), 
       
   106 					otherwise the output descriptors are left unchanged.
       
   107 */
       
   108 TInt CSIPUriParser::ParseAuthority(const TPtrC8& aUri, TPtrC8& aUserinfo, TPtrC8& aHost, TPtrC8& aPort, TBool aUseNetworkDelimiter)
       
   109 	{
       
   110 	// Get uri descriptor and see if authority exists - if aUseNetworkDelimiter is true it has to start with '//' 
       
   111 	TInt consumed =0;
       
   112 	const TInt prefixLength = aUseNetworkDelimiter ? KUriNetworkAuthorityDelimiterLength : 0;
       
   113   	if( !aUseNetworkDelimiter || 
       
   114   		(aUri.Length() >= prefixLength && aUri[0] == KSlashDelimiter && aUri[1] == KSlashDelimiter ))
       
   115 		{
       
   116 		// There is an authority
       
   117 		TPtrC8 authority( aUri.Mid(prefixLength) );
       
   118 
       
   119 		// Authority delimited by ';', '?' or the end of the string
       
   120 		TInt authorityEndPos = FindFirstUriDelimiter(authority, ESipAuthDelimiterSearch);
       
   121 
       
   122 		// Got authority - parse it for its components
       
   123 		authority.Set(authority.Left(authorityEndPos));
       
   124 
       
   125 		// Get the userinfo...
       
   126 		TInt userinfoEndPos = authority.Locate(KUserinfoDelimiter);
       
   127 		if( userinfoEndPos != KErrNotFound )
       
   128 			{
       
   129 			// Store the information 
       
   130 			aUserinfo.Set(authority.Left(userinfoEndPos));
       
   131 			  
       
   132 			// Move past the userinfo and the delimiter '@'
       
   133 			authority.Set(authority.Mid(userinfoEndPos + 1));
       
   134 			}
       
   135 
       
   136 		// Authority is also delimited by ';' but this is valid in the userinfo so can only be checked now
       
   137 		TInt semicolonPos = FindFirstUriDelimiter(authority, ESipSemiColonDelimiterFlag);
       
   138 		if ( semicolonPos != KErrNotFound )
       
   139 			{
       
   140 			authority.Set(authority.Left(semicolonPos));
       
   141 			authorityEndPos = semicolonPos + userinfoEndPos + 1;
       
   142 			}
       
   143 		
       
   144 		// Set consumed amount to move past authority
       
   145 		consumed += prefixLength + authorityEndPos;
       
   146 		
       
   147 		// Check if this is an IPv6 address	by looking for the opening '['
       
   148 		TInt startHostIPv6 = authority.Locate(KIPv6UriOpenBrace);
       
   149 
       
   150 		if (startHostIPv6 == KErrNotFound)
       
   151 			{
       
   152 			// This isn't an IPv6 address.....
       
   153 
       
   154 			// Get host...
       
   155 			TInt hostEndPos = authority.Locate(KPortDelimiter);
       
   156 
       
   157 			// Host also delimited by the end of the authority
       
   158 			if( hostEndPos == KErrNotFound )
       
   159 				{
       
   160 				hostEndPos = authority.Length();	
       
   161 				}
       
   162 
       
   163 			// There's always a host, but can be empty - store information
       
   164 			aHost.Set(authority.Left(hostEndPos));
       
   165 
       
   166 			// Move past the host
       
   167 			authority.Set(authority.Mid(hostEndPos));
       
   168 			}
       
   169 		else
       
   170 			{
       
   171 			// This is an IPv6 address, so it MUST have the closing brace too....
       
   172 			TInt endIPv6Host = authority.Locate(KIPv6UriCloseBrace);
       
   173 
       
   174 			// Return an error if the closing IPv6 delimiter isn't there.
       
   175 			// or Host is empty
       
   176 			if (endIPv6Host == KErrNotFound || endIPv6Host == startHostIPv6 + 1)
       
   177 				{
       
   178 				return KUriUtilsErrInvalidUri;	
       
   179 				}
       
   180 
       
   181 			// It's an ipv6  address, with an opening and closing brace. So now just extract it
       
   182 			// auth = [X:X:X]?????
       
   183 
       
   184 			// First, move past the opening brace
       
   185 			authority.Set(authority.Mid(startHostIPv6 + 1));
       
   186 			// auth now = X:X:X]?????
       
   187 
       
   188 			// Set the host, and need to remove the closing brace
       
   189 			aHost.Set(authority.Left(endIPv6Host - 1));
       
   190 			// host = X:X:X
       
   191 
       
   192 			// Move past the host
       
   193 			authority.Set(authority.Mid(endIPv6Host));
       
   194 			}
       
   195 		
       
   196 		// Get the port...
       
   197 		TInt portEndPos = authority.Length();
       
   198 		if( portEndPos )
       
   199 			{
       
   200 			// Store the port - remove leading ':'
       
   201 			aPort.Set(authority.Mid(1, portEndPos - 1));
       
   202 			}
       
   203 		}
       
   204 	return consumed;
       
   205 	}
       
   206 
       
   207 /**
       
   208 	Function to parse a descriptor for a path/parameter component.There is always a path component.
       
   209 	The ouput argument aPath is set to the path/parameter component found.
       
   210 						
       
   211 	@param			aUri	The descriptor containing the uri to be parsed for a path/parameter.
       
   212 	@param			aComponent	The output descriptor to refer to the path.
       
   213 	@return			The number of characters consumed in parsing the path.
       
   214 	@pre 			The output descriptor has been initialized so that the pointer
       
   215 					to the associated descriptor buffer is NULL. The input descriptor 
       
   216 					is set to the start of the path.
       
   217 					
       
   218 	@post			The output descriptor refers to the path component.
       
   219 */	
       
   220 TInt CSIPUriParser::ParsePath(const TPtrC8& aUri, TPtrC8& aComponent)
       
   221 	{
       
   222 	// Get descriptor with the path
       
   223 	TInt consumed =0;
       
   224 
       
   225 	// Path is delimited by '?' or the end of the string
       
   226 	TInt pathEndPos = FindFirstUriDelimiter(aUri, ESipPathDelimiterSearch);
       
   227 
       
   228 	// Check for presence of path
       
   229 	if( pathEndPos != KErrNotFound )
       
   230 		{
       
   231 		// Got path - store information
       
   232 		aComponent.Set(aUri.Left(pathEndPos));
       
   233 	
       
   234 		// Set consumed amount to move past path
       
   235 		consumed = pathEndPos;
       
   236 		}
       
   237 	return consumed;
       
   238 	}
       
   239 
       
   240 /**
       
   241 	Function to parse a descriptor for a query/header component.If a query is found then 
       
   242 	the output argument aQuery is set to refer to it.
       
   243 						
       
   244 	@param			aUri	The descriptor containing the uri to be parsed for a query/Header.
       
   245 	@param			aComponent	The output descriptor to refer to the query
       
   246 	@return			The number of characters consumed in parsing the query.
       
   247 	@pre 			The output descriptor has been initialized so that the pointer
       
   248 					to the associated descriptor buffer is NULL. The input descriptor is set to
       
   249 					the start of the query.
       
   250 	@post			If a query component exists then the output descriptor refers
       
   251 					to it, otherwise the output descriptor is left unchanged.
       
   252 */
       
   253 TInt CSIPUriParser::ParseQuery(const TPtrC8& aUri, TPtrC8& aComponent)
       
   254 	{
       
   255 	// Get descriptor with the query
       
   256 	TInt consumed =0;
       
   257 
       
   258 	// Query/Header is delimited by end of the string 
       
   259 	TInt queryEndPos = aUri.Length();
       
   260 
       
   261 	// Check for presence of query
       
   262 	if( queryEndPos )
       
   263 		{
       
   264 		// Got query - store information; need to excluded leading '?'
       
   265 		aComponent.Set(aUri.Mid(1, queryEndPos - 1));
       
   266 	
       
   267 		// Set consumed amount to move past query
       
   268 		consumed = queryEndPos;
       
   269 		}
       
   270 	return consumed;
       
   271 	}
       
   272 	
       
   273 /**
       
   274 	Function to parse a descriptor for a fragment component. 
       
   275 	In Sip Uris no Fragment Component it contains. This is an dummy implementation.
       
   276 						
       
   277 	@param			aUri not used.
       
   278 	@param			aComponent	not used.
       
   279 	@return			returns zero.
       
   280 */
       
   281 TInt CSIPUriParser::ParseFragment(const TPtrC8& /*aUri*/, TPtrC8& /* aComponent*/)
       
   282 	{
       
   283 	// Sip Uri Does not conatin Fragment
       
   284 	return 0;
       
   285 	}
       
   286 	
       
   287 /**
       
   288 	Function to find the position of the first delimiter in the descriptor specified 
       
   289 	by the delimiter flags. Note that the end of the descriptor is also a delimiter if there are 
       
   290 	no others. In the case of the scheme delimiter search, the position returned depends on the 
       
   291 	position of the colon delimiter with respect to the other delimiters for a scheme.
       
   292 						
       
   293 	@param			aUri The descriptor containing the section of a uri to be searched.
       
   294 	@param			aSearchFlag	The enum specifying the delimiters to search for.
       
   295 	@return			The position of nearest delimiter to start of the descriptor, where
       
   296 					zero is the start (left-most) position.
       
   297 */
       
   298 TInt CSIPUriParser::FindFirstUriDelimiter(const TPtrC8& aUri, TSipDelimiterSearchFlag aSearchFlag)
       
   299 	{
       
   300 	// Set ultimate delimiter - string length
       
   301 	TInt endPos = aUri.Length();
       
   302 
       
   303 	if( aSearchFlag & ESipQueryDelimiterFlag )
       
   304 		{
       
   305 		TInt queryPos = aUri.Locate(KQueryDelimiter);
       
   306 		if( queryPos != KErrNotFound && queryPos < endPos )
       
   307 			{
       
   308 			TInt userinfoPos = aUri.Locate(KUserinfoDelimiter);
       
   309 			//QueryDelimiter may be in Userinfo
       
   310 			if(userinfoPos != KErrNotFound && userinfoPos < endPos && userinfoPos > queryPos ) 
       
   311 				{
       
   312 				//Find QueryDelimiter after Userinfo
       
   313 				queryPos = aUri.Mid(userinfoPos).Locate(KQueryDelimiter);
       
   314 				if (queryPos != KErrNotFound  && queryPos < endPos )
       
   315 					{
       
   316 					queryPos += userinfoPos;	
       
   317 					}
       
   318 				}
       
   319 			if(queryPos != KErrNotFound)
       
   320 				{
       
   321 				endPos = queryPos;		
       
   322 				}
       
   323 			}
       
   324 		}
       
   325 
       
   326 	if( aSearchFlag & ESipSemiColonDelimiterFlag )
       
   327 		{
       
   328 		TInt semiColonPos = aUri.Locate(KParamDelimiter);
       
   329 		if( semiColonPos != KErrNotFound && semiColonPos < endPos )
       
   330 			{
       
   331 			TInt userinfoPos = aUri.Locate(KUserinfoDelimiter);
       
   332 			//ParamDelimiter may be in Userinfo
       
   333 			if(userinfoPos != KErrNotFound && userinfoPos < endPos && userinfoPos > semiColonPos ) 
       
   334 				{
       
   335 				//Find ParamDelimiter after Userinfo
       
   336 				semiColonPos = aUri.Mid(userinfoPos).Locate(KParamDelimiter);
       
   337 				if (semiColonPos != KErrNotFound  && semiColonPos < endPos )
       
   338 					{
       
   339 					semiColonPos += userinfoPos;	
       
   340 					}
       
   341 				}
       
   342 			if(semiColonPos != KErrNotFound)
       
   343 				{
       
   344 				endPos = semiColonPos;		
       
   345 				}
       
   346 			}
       
   347 		}
       
   348 	if( aSearchFlag & ESipColonDelimiterFlag )
       
   349 		{
       
   350 		TInt schemePos = aUri.Locate(KSchemeDelimiter);
       
   351 		if( schemePos != KErrNotFound && schemePos < endPos )
       
   352 			{
       
   353 			// There is a scheme
       
   354 			endPos = schemePos;
       
   355 			}
       
   356 		else if( aSearchFlag == ESipSchemeDelimiterSearch )
       
   357 			{
       
   358 			// Ok different if looking for scheme delimiter - no scheme, return KErrNotFound
       
   359 			endPos = KErrNotFound;
       
   360 			}
       
   361 		}
       
   362 	return endPos;
       
   363 	}
       
   364