genericservices/httputils/UriParser/TUriC.cpp
changeset 31 ce057bb09d0b
parent 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericservices/httputils/UriParser/TUriC.cpp	Fri Jun 04 16:20:51 2010 +0100
@@ -0,0 +1,1101 @@
+// 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:
+//
+
+// System includes
+#include <uri8.h>
+#include <uri16.h>
+#include "TUriCInternal.h"
+#include <uriutilscommon.h>
+#include <uriutils.h>
+#include "UriUtilsInternal.h"
+#include "TValidator.h"
+#include "TEquiv.h"
+#include <escapeutils.h>
+
+
+
+// Panic category
+//
+_LIT(KUriPanicCategory,"URI-BASE");
+
+//
+//
+// Implementation of TUriC8
+//
+//
+
+/**
+  Constructor.
+	
+  @since			6.0
+ */
+EXPORT_C TUriC8::TUriC8()
+	{
+	// Reset the component table and the Uri
+	Reset();
+	}
+
+/**
+  Retrieves the specified component in the uri.
+	
+  @since			6.0
+  @param			aComponent	The enum specifying the component.
+  @return			A constant reference to a descriptor pointer to the specified 
+  component.
+ */
+EXPORT_C const TDesC8& TUriC8::Extract(TUriComponent aComponent) const
+	{
+	__ASSERT_ALWAYS(aComponent<EUriMaxComponents && aComponent >EUriComplete, User::Panic(KUriPanicCategory, KUriUtilsErrBadComponentIndex));
+
+	return iComponent[aComponent];
+	}
+
+/**
+  Indicates whether the specified component is present in the uri.
+	
+  @since			6.0
+  @param			aComponent	The enum specifying the component.
+  @return			A boolean value of ETrue if the desired component is present, 
+  or EFalse if the desired component is not present.
+ */
+EXPORT_C TBool TUriC8::IsPresent(TUriComponent aComponent) const
+	{
+	__ASSERT_ALWAYS(aComponent<EUriMaxComponents && aComponent >EUriComplete, User::Panic(KUriPanicCategory, KUriUtilsErrBadComponentIndex));
+
+	return TBool(iComponent[aComponent].Ptr());
+	}
+
+/**
+  Checks the scheme to be valid. If there is no scheme then the return value 
+  indicates an invalid scheme.
+	
+  @since			6.0
+  @return			A boolean value of ETrue if the scheme is valid, or EFalse if
+  the scheme is not.
+ */
+EXPORT_C TBool TUriC8::IsSchemeValid() const
+	{
+	if( !IsPresent(EUriScheme) )
+		{
+		return EFalse;
+		}
+	return HasValidSchemeChars(iComponent[EUriScheme]);
+	}
+
+/**
+  Compares the specified component against the one in the uri passed in.
+	
+  @since			6.0
+  @param			aUri		The uri to compare components against.
+  @param			aComponent	The enum specifying the component to compare.
+  @return			An integer value of zero if the components are the same,
+  any other value if the components are not the same.
+ */
+EXPORT_C TInt TUriC8::Compare(const TUriC8& aUri, TUriComponent aComponent) const
+	{
+	__ASSERT_ALWAYS(aComponent<EUriMaxComponents && aComponent >EUriComplete, User::Panic(KUriPanicCategory, KUriUtilsErrBadComponentIndex));
+
+	// Does the component exist in both the Uri's
+	if( IsPresent(aComponent) && aUri.IsPresent(aComponent) )
+		{
+		if( aComponent == EUriScheme || aComponent == EUriHost )
+			{
+			// Do case insensitive compare for scheme and host
+			return (iComponent[aComponent].CompareF(aUri.iComponent[aComponent]));
+			}
+		else
+			{
+			// Do case sensitive compare for all other components
+			return (iComponent[aComponent].Compare(aUri.iComponent[aComponent]));
+			}
+		}
+	else
+		return KErrNotFound;
+	}
+
+/**
+  Retrieves the descriptor for the entire uri.
+	
+  @since			6.0
+  @return			A const reference to a descriptor pointer to the uri.
+ */
+EXPORT_C const TDesC8& TUriC8::UriDes() const
+	{
+	return iUriDes;
+	}
+
+/**
+  @publishedPartner
+  @released
+  Ensures that all components of the URI are valid. If the method	returns 
+  KUriUtilsErrInvalidUri then one or more components are not valid. It is
+  possible for URIs declared valid by this method to be, on detailed inspection, 
+  invalid.
+	
+  @return	KErrNone for vaild URIs, KUriUtilsErrInvalidUri for invalid URIs or KErrNotSupported.
+ */
+EXPORT_C TInt TUriC8::Validate() const
+	{
+	return DoValidate(*this);
+	}
+
+/**
+  Compares the given URI to determine if it is equivalent to this URI. It is possible
+  for URIs declared NOT equivalent by this method to be equvalent to a level not checked 
+  by this method.
+  @publishedPartner
+  @released
+  @param			aUri	Contains URI to compare 
+  @return			ETrue if the two URIs are equivalent otherwise EFalse
+ */
+EXPORT_C TInt TUriC8::Equivalent(const TUriC8& aUri) const
+	{
+	TInt result = EFalse;
+	TRAPD(error, result = DoEquivalenceL(*this, aUri));
+	if (error != KErrNone)
+		{
+		result = error;
+		}
+	return result;
+	}
+
+/**
+  Retrieves the uri without the fragment component.
+	
+  @since			6.0
+  @param			aUriNoFrag	An output parameter which is set the non-reference 
+  version of the uri.
+ */
+EXPORT_C void TUriC8::UriWithoutFragment(TPtrC8& aUriNoFrag) const
+	{
+	if( IsPresent(EUriFragment) )
+		{
+		// There is a fragment, find where it starts
+		TInt fragmentStartPos = iUriDes.Locate(KFragmentDelimiter);
+		aUriNoFrag.Set(iUriDes.Left(fragmentStartPos));
+		}
+	else{
+		aUriNoFrag.Set(iUriDes);
+		}
+	}
+
+/** 
+  Create a new HBufC descriptor containing the desired component or the full URI.
+	
+  @param    aComponent  The component to convert into Unicode (EUriScheme - EUriFragment),  or
+  the full URI (EUriComplete -- the default).
+  @return    The descriptor containing the desired component. 
+ */
+EXPORT_C HBufC* TUriC8::DisplayFormL(TUriComponent aComponent) const
+	{
+	TPtrC8 component;	
+	
+	if (aComponent == EUriComplete) 
+		{
+		component.Set(iUriDes);
+		}
+	else 
+		{  // extract the specified component, will Panic if invalid
+		component.Set( Extract(aComponent) );
+		}
+	// convert descriptor from UTF-8 into Unicode
+	return EscapeUtils::ConvertToUnicodeFromUtf8L(component);
+	}
+
+/**
+  @internalComponent
+  Resets the descriptor pointers for the uri components and the uri.
+	
+  @since		6.0
+  @post			All uri component information is removed and the uri descriptor is 
+  set to NULL.
+ */
+void TUriC8::Reset()
+	{
+	// Set descriptor pointers to NULL and lengths to zero
+	for( TInt i=0; i<EUriMaxComponents; ++i )
+		{
+		iComponent[i].Set(NULL,0);
+		}
+	iUriDes.Set(NULL,0);
+	}
+	
+//
+//
+// Implementation of TUriC16
+//
+//
+/**
+  Constructor.
+	
+  @since		6.0
+  @deprecated 	Deprecated in 9.1
+ */
+EXPORT_C TUriC16::TUriC16()
+	{
+	// Reset the component table and the Uri
+	Reset();
+	}
+
+/**
+  Retrieves the specified component in the uri.
+	
+  @since			6.0
+  @deprecated 		Deprecated in 9.1
+  @param			aComponent	The enum specifying the component.
+  @return			A constant reference to a descriptor pointer to the specified component.
+ */
+EXPORT_C const TDesC16& TUriC16::Extract(TUriComponent aComponent) const
+	{
+	__ASSERT_ALWAYS(aComponent<EUriMaxComponents && aComponent >EUriComplete, User::Panic(KUriPanicCategory, KUriUtilsErrBadComponentIndex));
+
+	return iComponent[aComponent];
+	}
+
+/**
+  Indicates whether the specified component is present in the uri.
+	
+  @since			6.0
+  @deprecated Deprecated in 9.1
+  @param			aComponent	The enum specifying the component.
+  @return			A boolean value of ETrue if the desired component is present, 
+  or EFalse if the desired component is not present.
+ */
+EXPORT_C TBool TUriC16::IsPresent(TUriComponent aComponent) const
+	{
+	__ASSERT_ALWAYS(aComponent<EUriMaxComponents && aComponent >EUriComplete, User::Panic(KUriPanicCategory, KUriUtilsErrBadComponentIndex));
+
+	return TBool(iComponent[aComponent].Ptr());
+	}
+
+/**
+  Checks to see if the scheme is valid. If there is no scheme then the return value 
+  indicates an invalid scheme (EFalse).
+	
+  @since		6.0
+  @deprecated 	Deprecated in 9.1
+  @return		A boolean value of ETrue if the scheme is valid, or EFalse if
+  the scheme is not.
+ */
+EXPORT_C TBool TUriC16::IsSchemeValid() const
+	{
+	if( !IsPresent(EUriScheme) )
+		{
+		return EFalse;
+		}
+	return HasValidSchemeChars(iComponent[EUriScheme]);
+	}
+
+/**
+  Compares the specified component against the one in the uri passed in.
+	
+  @since		6.0
+  @deprecated 	Deprecated in 9.1
+  @param		aUri		The uri to compare components against.
+  @param		aComponent	The enum specifying the component to compare.
+  @return		An integer value of zero if the components are the same, any other
+  value if the components are not the same.
+ */
+EXPORT_C TBool TUriC16::Compare(const TUriC16& aUri, TUriComponent aComponent) const
+	{
+	__ASSERT_ALWAYS(aComponent<EUriMaxComponents && aComponent >EUriComplete, User::Panic(KUriPanicCategory, KUriUtilsErrBadComponentIndex));
+
+	// Does the component exist in both the Uri's
+	if( IsPresent(aComponent) && aUri.IsPresent(aComponent) )
+		{
+		if( aComponent == EUriScheme || aComponent == EUriHost )
+			{
+			// Do case insensitive compare for scheme and host
+			return (iComponent[aComponent].CompareF(aUri.iComponent[aComponent]));
+			}
+		else
+			{
+			// Do case sensitive compare for all other components
+			return (iComponent[aComponent].Compare(aUri.iComponent[aComponent]));
+			}
+		}
+	else
+		return KErrNotFound;
+	}
+
+/**
+  Retrieves the descriptor for the entire uri.
+	
+  @since			6.0
+  @deprecated Deprecated in 9.1
+  @return			A const reference to a descriptor pointer to the uri.
+ */
+EXPORT_C const TDesC16& TUriC16::UriDes() const
+	{
+	return iUriDes;
+	}
+
+/**
+  @deprecated Deprecated in 9.1 -- provided for compatibility
+	
+  Ensures that all components of the URI are valid. If the method	returns 
+  KUriUtilsErrInvalidUri then one or more components are not valid. It is possible
+  for URIs declared valid by this method to be, on detailed inspection, invalid.
+	
+  @return			KErrNone for vaild URIs, KUriUtilsErrInvalidUri for invalid URIs or KErrNotSupported.
+ */
+EXPORT_C TInt TUriC16::Validate() const
+	{
+	TInt result = KErrNone;
+	TRAPD(error, result = ValidateL());
+	if (error)
+		{
+		// problem allocating resourses 
+		return error;
+		}
+	return result;
+	}
+
+/**
+  @deprecated Deprecated in 9.1 -- provided for compatibility
+
+  Compares the given URI to determine if it is equivalent to this URI. It is possible
+  for URIs declared NOT equivalent by this method to be equvalent to a level not checked 
+  by this method.
+  @param			aUri	Contains URI to compare 
+  @return			ETrue if the two URIs are equivalent otherwise EFalse
+ */
+EXPORT_C TInt TUriC16::Equivalent(const TUriC16& aUri) const
+	{
+	TInt result = KErrNone;
+	TRAPD(error, result = EquivalentL(aUri.UriDes()));
+	if (error)
+		{
+		// problem allocating resourses 
+		return error;
+		}
+	return result;
+	}
+/**
+  Retrieves the uri without the fragment component.
+	
+  @since			6.0
+  @deprecated Deprecated in 9.1
+  @param			aUriNoFrag	An output parameter which is set the non-reference 
+  version of the uri.
+ */
+
+EXPORT_C void TUriC16::UriWithoutFragment(TPtrC16& aUriNoFrag) const
+	{
+	if( IsPresent(EUriFragment) )
+		{
+		// There is a fragment, find where it starts
+		TInt fragmentStartPos = iUriDes.Locate(KFragmentDelimiter);
+		aUriNoFrag.Set(iUriDes.Left(fragmentStartPos));
+		}
+	else{
+		aUriNoFrag.Set(iUriDes);
+		}
+	}
+
+/** 
+  Create a new HBufC descriptor containing the desired component or the full URI.
+  @deprecated Deprecated in 9.1 - provided for compatibility	
+  
+  @param aComponent  The component to convert into Unicode (EUriScheme - EUriFragment),  or
+  the full URI (EUriComplete -- the default).
+  @return The descriptor containing the desired component. 
+ */
+EXPORT_C HBufC* TUriC16::DisplayFormL(TUriComponent aComponent) const
+	{
+	if ( aComponent == EUriComplete) // extract the full URI
+		{
+		return iUriDes.AllocL();	
+		}
+	return Extract(aComponent).AllocL();
+	}
+
+/**	
+  @internalComponent
+  Resets the descriptor pointers for the uri components and the uri.
+	
+  @since			6.0
+  @post			All uri component information is removed and the uri descriptor is 
+  set to NULL.
+ */
+void TUriC16::Reset()
+	{
+	// Set descriptor pointers to NULL and lengths to zero
+	for( TInt i=0; i<EUriMaxComponents; ++i )
+		{
+		iComponent[i].Set(NULL,0);
+		}
+	iUriDes.Set(NULL,0);
+	}
+
+/**
+  @deprecated Deprecated in 9.1 
+	
+  Ensures that all components of the URI are valid. If the method	returns 
+  KUriUtilsErrInvalidUri then one or more components are not valid. It is possible
+  for URIs declared valid by this method to be, on detailed inspection, invalid.
+	
+  @return			KErrNone for vaild URIs, KUriUtilsErrInvalidUri for invalid URIs or KErrNotSupported.
+ */
+TInt TUriC16::ValidateL() const
+	{
+	TInt result;
+	
+	HBufC8* uri8 = CreateUri8LC(UriDes());
+	TUriParser8 uriParser;		
+	if(uriParser.Parse(*uri8) != KErrNone)
+		{
+		result = KUriUtilsErrInvalidUri;
+		}
+	else		
+		{
+		result = DoValidate(uriParser);		
+		}
+	
+	CleanupStack::PopAndDestroy(uri8);
+	return result;	
+	}
+
+/**
+  @deprecated Deprecated in 9.1 
+
+  Compares the given URI to determine if it is equivalent to this URI. It is possible
+  for URIs declared NOT equivalent by this method to be equvalent to a level not checked 
+  by this method.
+  @param			aUri	Contains URI to compare 
+  @return			ETrue if the two URIs are equivalent otherwise EFalse
+ */
+TBool TUriC16::EquivalentL(const TDesC16& aUri) const
+	{
+	HBufC8* lhs = CreateUri8LC(UriDes());
+	HBufC8* rhs = CreateUri8LC(aUri);
+	
+	TUriParser8 lhsParser;		
+	if(lhsParser.Parse(*lhs) != KErrNone)
+		{
+		User::Leave(KUriUtilsErrInvalidUri);
+		}
+		
+	TUriParser8 rhsParser;		
+	if(rhsParser.Parse(*rhs) != KErrNone)
+		{
+		User::Leave(KUriUtilsErrInvalidUri);
+		}
+	
+	TBool result = DoEquivalenceL(lhsParser, rhsParser);		
+	
+	CleanupStack::PopAndDestroy(2);
+	return result;	
+	}
+
+//
+//
+// Implementation of LOCAL functions
+//
+//
+
+/**
+	Checks the scheme for invalid characters. The scheme is invalid if it is empty.
+						
+	@since			6.0
+	@param			aScheme	The descriptor with the scheme.
+	@return			A boolean value of ETrue if all the characters in the scheme
+	are valid, otherwise EFalse.
+*/
+template<class TPtrCType>
+LOCAL_C TBool HasValidSchemeChars(const TPtrCType& aScheme)
+	{
+	TInt length = aScheme.Length();
+	TBool valid = ( length && TChar(aScheme[0]).IsAlpha() );
+
+	// Start checking from the second character
+	TInt i=1;
+	while( valid && i<length )
+		{
+		TChar c = aScheme[i];
+		valid = c.IsAlphaDigit() || c==KPlusChar || c==KMinusChar || c==KPeriodChar;
+		++i;
+		}
+	return valid;
+	}
+
+
+//
+//
+// File URI Implementation - CUri8
+//
+//
+#ifdef __SECURE_DATA__	
+/**
+	Generates a fully-qualified filename from a file URI object.
+
+	The form of the returned filename depends on the file location, as follows: 	
+	- public file on a fixed drive: 
+		@code
+		file://c/path/to/file/name.ext -> c:\path\to\file\name.ext
+		@endcode
+
+	- public file on removable media drive:
+	 The fully-qualified filename is resolved by finding the first drive on which the file exists.
+	 If the file does not exist, this will Leave with KErrNotFound
+	 	@code
+		file://ext-media/path/to/file/name.ext -> f:\path\to\file\name.ext
+		@endcode
+		 (where f: is the first drive found containing "\path\to\file\name.ext")
+		 
+	- private file on fixed drive:
+		@code
+		file://private/c/path/to/file/name.ext -> c:\private\0x1001234f\path\to\file\name.ext
+		@endcode
+		 (where 0x1001234f is the SID of the current application)
+
+	- private file on removable media drive:
+		@code
+		file://private/ext-media/path/to/file/name.ext -> h:\private\0x1001234f\path\to\file\name.ext
+		@endcode
+		 (where h: is the first drive found containing "\private\0x1001234f\path\to\file\name.ext")
+
+	The returned file name is not guaranteed to exist except where specified above.
+
+	Be warned that this method may be slow when resolving special paths (like "/ext-media")
+	
+	@leave			KErrNotSupported URI does not specify a local file
+	@leave			KErrNotFound If the URI indicates the file is on removable media and the file does not exist on any.
+	@since			9.1
+	@return			A descriptor containing the fully-qualified filename. 
+	@pre 			Object is fully constructed.
+ */
+#else
+ /**
+	Generates a fully-qualified filename from a file URI object.
+
+	The form of the returned filename depends on the file location, as follows: 	
+	- public file on a fixed drive: 
+		@code
+		file://c/path/to/file/name.ext -> c:\path\to\file\name.ext
+		@endcode
+
+	- public file on removable media drive:
+	 The fully-qualified filename is resolved by finding the first drive on which the file exists.
+	 If the file does not exist, this will Leave with KErrNotFound
+	 	@code
+		file://ext-media/path/to/file/name.ext -> f:\path\to\file\name.ext
+		@endcode
+		 (where f: is the first drive found containing "\path\to\file\name.ext")
+
+	The returned file name is not guaranteed to exist except where specified above.
+
+	Be warned that this method may be slow when resolving special paths (like "/ext-media")
+	
+	@leave			KErrNotSupported URI does not specify a local file
+	@leave			KErrNotFound If the URI indicates the file is on removable media and the file does not exist on any.
+	@since			9.1
+	@return			A descriptor containing the fully-qualified filename. 
+	@pre 			Object is fully constructed.
+ */
+ #endif
+EXPORT_C HBufC* TUriC8::GetFileNameL() const
+	{
+	return GetFileNameL(EUriFileNameFull);
+	}
+
+
+/**
+	This creates a file name from the URI, changing the network path separator (/) to the 
+	local file system path separator (\\). 
+	
+	If called with EUriFileNamePath, this will generate a file name containing  the path relative to the drive. 
+	Any parameters in the URI are stripped off:
+		@code
+		http://www.foo.com/dir/file/name.ext;param1;param2 -> \dir\file\name.ext
+		@endcode
+	
+	If called with EUriFileNameTail, this will generate a just the name, with no directories or drive.
+	Any parameters in the URI are stripped off:
+		@code
+		http://www.foo.com/dir/file/name.ext;param1;param2 -> name.ext
+		@endcode
+	
+	EUriFileNamePath and EUriFileNameTail can be used for any hierarchical URI (http, ftp, file, etc)
+	and may have unexpected behaviour when called on any other type of URI.
+
+	If called with EUriFileNameFull, this will convert the URI into a fully-qualified filename. this is only valid
+	for file URIs and will Leave if called on any other type of URI. The form of the returned filename is described in 
+	GetFileNameL with no arguments.
+	
+	@leave			KErrNotSupported The URI scheme cannot be converted into the desired  type
+	@since			9.1
+	@pre 			Object is fully constructed.
+	@param			aType specifies what part of the filename is to be  converted. The default is EUriFileNameFull).
+	@return			A descriptor containing the desired filename components.
+ */
+EXPORT_C HBufC* TUriC8::GetFileNameL(TUriFileName aType) const
+	{
+	TBool isFileUri = Extract(EUriScheme).Compare(KFileUriScheme8) == 0;
+	if(aType == EUriFileNameFull && !isFileUri)
+		{		
+		User::Leave(KErrNotSupported);
+		}
+	return ResolveFileNameL(Extract(EUriPath), aType, isFileUri);
+	}
+	
+
+//
+//
+// File URI Implementation - CUri16
+//
+//
+
+#ifdef  __SECURE_DATA__
+/**
+	Generates a fully-qualified filename from a file URI object.
+
+	The form of the returned filename depends on the file location, as follows: 	
+	- public file on a fixed drive: 
+		@code
+		file://c/path/to/file/name.ext -> c:\path\to\file\name.ext
+		@endcode
+
+	- public file on removable media drive:
+	 The fully-qualified filename is resolved by finding the first drive on which the file exists.
+	 If the file does not exist, this will Leave with KErrNotFound
+		@code
+		file://ext-media/path/to/file/name.ext -> f:\path\to\file\name.ext
+		@endcode
+		 (where f: is the first drive found containing "\path\to\file\name.ext")
+
+	- private file on fixed drive:
+		@code
+		file://private/c/path/to/file/name.ext -> c:\private\0x1001234f\path\to\file\name.ext
+		@endcode
+		 (where 0x1001234f is the SID of the current application)
+
+	- private file on removable media drive:
+		@code
+		file://private/ext-media/path/to/file/name.ext -> h:\private\0x1001234f\path\to\file\name.ext
+		@endcode
+		 (where h: is the first drive found containing "\private\0x1001234f\path\to\file\name.ext")
+
+	The returned file name is not guaranteed to exist except where specified above.
+
+	Be warned that this method may be slow when resolving special paths (like "/ext-media")
+	
+	@leave			KErrNotSupported URI does not specify a local file
+	@leave			KErrNotFound If the URI indicates the file is on removable media and the file does not exist on any.
+	@since			9.1
+	@return			A descriptor containing the fully-qualified filename. 
+	@pre 			Object is fully constructed.
+	
+ */
+#else 
+/**
+	Generates a fully-qualified filename from a file URI object.
+
+	The form of the returned filename depends on the file location, as follows: 	
+	- public file on a fixed drive: 
+		@code
+		file://c/path/to/file/name.ext -> c:\path\to\file\name.ext
+		@endcode
+
+	- public file on removable media drive:
+	 The fully-qualified filename is resolved by finding the first drive on which the file exists.
+	 If the file does not exist, this will Leave with KErrNotFound
+		@code
+		file://ext-media/path/to/file/name.ext -> f:\path\to\file\name.ext
+		@endcode
+		 (where f: is the first drive found containing "\path\to\file\name.ext")
+
+	The returned file name is not guaranteed to exist except where specified above.
+
+	Be warned that this method may be slow when resolving special paths (like "/ext-media")
+	
+	@leave			KErrNotSupported URI does not specify a local file
+	@leave			KErrNotFound If the URI indicates the file is on removable media and the file does not exist on any.
+	@since			9.1
+	@return			A descriptor containing the fully-qualified filename. 
+	@pre 			Object is fully constructed.
+	
+ */
+ #endif
+EXPORT_C HBufC* TUriC16::GetFileNameL() const
+	{
+	return GetFileNameL(EUriFileNameFull);
+	}
+
+
+/**
+	This creates a file name from the URI, changing the network path separator (/) to the 
+	local file system path separator (\\). 
+	
+	If called with EUriFileNamePath, this will generate a file name containing  the path relative to the drive. 
+	Any parameters in the URI are stripped off:
+		@code
+		http://www.foo.com/dir/file/name.ext;param1;param2 -> \dir\file\name.ext
+		@endcode
+	
+	If called with EUriFileNameTail, this will generate a just the name, with no directories or drive.
+	Any parameters in the URI are stripped off:
+		@code
+		http://www.foo.com/dir/file/name.ext;param1;param2 -> name.ext
+		@endcode
+	
+	EUriFileNamePath and EUriFileNameTail can be used for any hierarchical URI (http, ftp, file)
+	and may have unexpected behaviour when called on any other type of URI.
+
+	If called with EUriFileNameFull, this will convert the URI into a fully-qualified filename. this is only valid
+	for file URIs and will Leave if called on any other type of URI. The form of the returned filename is described in 
+	GetFileNameL with no arguments.
+	
+	@leave			KErrNotSupported The URI scheme cannot be converted into the desired  type
+	@since			9.1
+	@pre 			Object is fully constructed.
+	@param			aType specifies what part of the filename is to be converted. The default is (EUriFileNameFull).
+	@return			A descriptor containing the desired filename components.
+ */
+EXPORT_C HBufC* TUriC16::GetFileNameL(TUriFileName aType) const
+	{
+	TBool isFileUri = Extract(EUriScheme).Compare(KFileUriScheme16) == 0;
+
+	if(aType == EUriFileNameFull &&  !isFileUri )
+		{		
+		User::Leave(KErrNotSupported);
+		}		
+
+	HBufC8* fileUriPath8 = HBufC8::NewLC(Extract(EUriPath).Length());
+	fileUriPath8->Des().Copy(Extract(EUriPath));
+	HBufC* absFileName = ResolveFileNameL(*fileUriPath8, aType, isFileUri);
+	CleanupStack::PopAndDestroy(fileUriPath8);
+	return absFileName;
+	}
+
+
+//
+//
+// Implementation of LOCAL functions
+//
+//
+
+/**
+  Function used to convert '\' to '/' and vice versa.
+	
+  @since			9.1
+  @param			aDesPtr				A descriptor reference to the string.
+  @param			aPathSeperatorFrom	A path seperator to be converted (from)
+  @param			aPathSeperatorTo 	A path seperator to converte (To).
+ */
+void ChangePathSeparator(TDes& aDesPtr, TUint aPathSeperatorFrom, TUint aPathSeperatorTo)
+	{
+	for(TInt offset = aDesPtr.Length() - 1;offset >= 0;offset--)
+		{
+		if (aDesPtr[offset] == aPathSeperatorFrom)
+			{	
+				aDesPtr[offset] = TUint16(aPathSeperatorTo);
+			}
+		}
+	}
+
+/**
+  Function used to generate a fully qualified file name for a public or private file 
+  stored on a fix drive or a removable media drive from File URI path (parameter aFileUriPath).
+	
+  This will be called by API GetFileName() to generate and return a filename.
+	
+  @leave			KErrBadName 	if the path doesn't contain valid drivename.
+  @since			9.1
+  @param			aFileUriPath	A descriptor reference to the File URI's path component.
+  @return			A pointer to a buffer containing the resolved fully qualified filename 
+					if the file uri path is not empty or a top level dir on main drive (C:\\)
+ */
+HBufC* GetFullFileNameFromFileUriPathL(const TDesC& aFileUriPath)
+	{	
+	TFileName filename(KDefaultPath);
+	
+	TInt origLength = aFileUriPath.Length();
+	if(origLength == 0)
+		{
+		return filename.AllocL();
+		}
+		
+	TInt index = 0;
+ 	TPtrC fileUriPath(aFileUriPath);
+ 	
+ 	//skip KUriPathSeparator (/) from the Uri path
+ 	if (fileUriPath[0] == KUriPathSeparator)
+  		{
+		index++;
+		}
+	
+	fileUriPath.Set(aFileUriPath.Right(origLength - index));
+
+	RFs fs;
+	TBool fsOpen = EFalse;
+				
+#ifdef __SECURE_DATA__			
+	if (fileUriPath.Left(KPrivate().Length()).Compare(KPrivate) == 0)
+		{
+		index += KPrivate().Length();
+		User::LeaveIfError(fs.Connect());
+		CleanupClosePushL(fs);		
+		fsOpen = ETrue;
+		User::LeaveIfError(fs.PrivatePath(filename));
+		filename.Insert(0, KDefaultPath().Left((KDefaultPath().Length() - 1) )); //Insert <drive>: 
+		fileUriPath.Set(aFileUriPath.Right(origLength - index));
+		}
+#endif
+	
+	TBool isExtMedia = (fileUriPath.Left(KExtMedia().Length()).Compare(KExtMedia) == 0);
+	if (!isExtMedia )
+		{
+		TUint driveLetter = fileUriPath[0];	
+		//Checking for valid driveletter (should between A to Z or a to z) and followed by Uri path seperator "/"
+		if ( fileUriPath[1] != KUriPathSeparator ||
+		 (  (driveLetter < 'A' || driveLetter > 'Z') && 
+			(driveLetter < 'a' || driveLetter > 'z')  )  )
+			{
+			User::Leave(KErrBadName);
+			}
+		index += (KDefaultPath().Length() - 1); //skip <driveLetter>/
+		filename[0] = TUint16(driveLetter); 
+		}
+	else
+		{
+		index += KExtMedia().Length();
+		}
+		
+	filename.Append(aFileUriPath.Right(origLength - index));
+		
+	//Convert "/" to "\"
+	ChangePathSeparator(filename, KUriPathSeparator, KFilePathSeparator);
+
+	if (isExtMedia )
+		{		
+		if (fsOpen == EFalse)
+			{
+			User::LeaveIfError(fs.Connect());
+			CleanupClosePushL(fs);		
+			fsOpen = ETrue;	
+			}
+		
+		TDriveInfo driveInfo;
+		TInt err = KErrNotFound;
+
+		for (TInt driveNum = EDriveA; driveNum <= EDriveZ && err!=KErrNone; driveNum++)   
+			{
+			if (fs.Drive(driveInfo, driveNum ) == KErrNone
+    			&& (driveInfo.iDriveAtt & KDriveAttRemovable))       
+    			{
+    			filename[0]= TInt16('A' + driveNum);
+    			TUint attValue;
+    			err = fs.Att(filename, attValue);
+    			}
+			}
+  		User::LeaveIfError(err);
+		}
+							
+	if (fsOpen)
+		{
+		CleanupStack::PopAndDestroy(&fs);
+		}
+		
+	return filename.AllocL();	
+	}
+
+/**
+  Creates an 8 bit URI descriptor from an 16  bit one
+	
+  @param			aBuf16	The full 16 bit URI descriptor
+  @return			Pointer to the newly created 8 bit URI descriptor
+					are valid, otherwise EFalse.
+*/
+HBufC8* CreateUri8LC(const TDesC16& aBuf16)
+	{
+	TInt length = aBuf16.Length();
+	HBufC8* newBuf = HBufC8::NewMaxLC(length);
+	TPtr8 des8Ptr = newBuf->Des();
+	for (TInt i = 0; i < length; ++i)
+		{
+		des8Ptr[i] = static_cast<TText8>(aBuf16[i]);
+		}
+	return newBuf;
+	}
+
+/**
+  Check the components of a URI to ensure they are all valid
+	
+  @since			8.1
+  @param			aUri The URI to check
+  @return			KErrNone if all components are valid, otherwise one of the 'invalid' error codes
+*/
+TInt DoValidate(const TUriC8& aUri)
+	{
+	TInt result;
+	TPtrC8 subComponent(aUri.Extract(EUriScheme));
+	if (!HasValidSchemeChars(subComponent))
+		{
+		result = KUriUtilsErrInvalidScheme;
+		}
+	else if(SchemeType(subComponent) == ESchemeTypeSip) 
+		//To validate Sip uri
+		{
+		TValidatorSip validator(aUri);
+		result = validator.Validate();		
+		}	
+	else if(SchemeType(subComponent) == ESchemeTypeTel) 
+		//To validate Tel uri
+		{
+		TValidatorTel validator(aUri);
+		result = validator.Validate();
+		}
+	else		
+		{
+		result = KErrNotSupported;		
+		}
+		
+	return result;
+	}
+
+/**
+  Compare the components of two URIs to see if they identify the same resource
+	
+  @since			8.1
+  @param			aLhs The left hand side URI to compare
+  @param			aRhs The right hand side URI to compare
+  @return			ETrue if they point to the same resource, EFalse otherwise.
+*/
+TInt DoEquivalenceL(const TUriC8& aLhs, const TUriC8& aRhs)
+	{
+	TInt result;
+	if (SchemeType(aLhs.Extract(EUriScheme)) == ESchemeTypeSip)
+		{
+		TEquivSip equiv(aLhs, aRhs);
+		result = equiv.EquivalentL();
+		}
+	else
+		{
+		// unknown scheme so assume network scheme
+		TEquiv equiv(aLhs, aRhs);
+		result = equiv.EquivalentL();
+		}
+	
+	return result;
+	}
+
+
+/**
+  Get the desired part of the filename from the URI path
+	
+  @param			aPath A descriptor reference to the File URI's path component.
+  @param			aType enum value of TUriFileName.
+  @param			aIsFileUri Specifies the whether it is FileUri or not.
+  @return			Pointer to the newly created URI descriptor which contains the 
+  					desired part of the filename from the URI path.
+*/
+HBufC* ResolveFileNameL(const TDesC8& aPath, TUriFileName aType, TBool aIsFileUri)
+	{	
+	// replace % codes
+	HBufC8* fileUriPath8 = EscapeUtils::EscapeDecodeL(aPath);
+	CleanupStack::PushL(fileUriPath8);
+	
+	// convert to unicode 
+	HBufC* fileUriPath = EscapeUtils::ConvertToUnicodeFromUtf8L(*fileUriPath8);
+	CleanupStack::PopAndDestroy(fileUriPath8);
+	CleanupStack::PushL(fileUriPath);			
+
+	HBufC* absFileName = NULL; // setting to NULL makes compiler happy
+	if ( aIsFileUri )
+		{ 
+		/* awlays do full conversion for file URIs
+		 It's not optimal time-wise, but it uses the least code and is
+		 forward-compatible. */
+		absFileName = GetFullFileNameFromFileUriPathL(*fileUriPath);		
+		CleanupStack::PopAndDestroy(fileUriPath);
+		if ( aType == EUriFileNameFull )
+			{	
+			return absFileName;
+			}
+		fileUriPath = absFileName;	// code below uses fileUriPath
+		CleanupStack::PushL(fileUriPath);			
+		TPtr path(fileUriPath->Des());
+		path.Delete(0,2);	// delete drive and ':' (always begins with drive letter and :)
+		}
+	else  // not a file URI
+		{ // convert '/' to '\' for all other URIs
+		TPtr path(fileUriPath->Des());
+		ChangePathSeparator(path, KUriPathSeparator, KFilePathSeparator);
+		}
+		
+	// EUriFileNameFull must only ever be used with a file URI. Failures should be caught by the caller
+	__ASSERT_DEBUG(aType != EUriFileNameFull, 
+		User::Panic(KUriPanicCategory, KUriUtilsErrBadComponentIndex));
+	
+	TPtrC name;
+	GetFileComponent(name, *fileUriPath, aType ); // get path or tail
+	if (name.Length() == fileUriPath->Length()) 
+		{ // no changes, just return fileUriPath
+		absFileName = fileUriPath;
+		CleanupStack::Pop(fileUriPath);
+		}
+	else
+		{
+		absFileName = name.AllocL();
+		CleanupStack::PopAndDestroy(fileUriPath); 
+		}
+	
+	return absFileName;
+	}
+
+/**
+  Gets the desired file path or tail.
+	
+  @param			aNewName An outparameter, reference to descriptor .
+  @param			aOldName An inparameter descriptor reference.
+  @param			aType enum value of TUriFileName.
+ */
+void GetFileComponent(TPtrC& aNewName, const TDesC& aOldName, TUriFileName aType )
+	{
+	__ASSERT_ALWAYS(aType != EUriFileNameFull, User::Panic(KUriPanicCategory, KUriUtilsErrBadComponentIndex));
+
+	aNewName.Set(aOldName);
+	// chop off everything after the first ;
+	TInt pos = aNewName.Locate(KParamDelimiter);
+	if( pos == 0 ) // the ; is at the start
+		{	
+		aNewName.Set(KNullDesC);
+		}
+	else if (pos > 0)
+		{ // set to the text untilt he ;
+		aNewName.Set(aNewName.Left(pos));
+		}
+	if( aType == EUriFileNameTail)
+		{	
+		// chop off everything before the last /
+		TInt pos = aNewName.LocateReverse(KFilePathSeparator);
+		if( pos >=0 ) // there is a /
+			{
+			if( pos >= aNewName.Length() - 1 ) // the / is at the end
+				{
+				aNewName.Set(KNullDesC);
+				}
+			else
+				{ // set to the text following the last /
+				aNewName.Set(aNewName.Right(aNewName.Length()-1-pos));
+				}
+			}
+		}
+	}
+
+
+
+