genericservices/httputils/UriParser/CUri.cpp
changeset 0 e4d67989cc36
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/genericservices/httputils/UriParser/CUri.cpp	Tue Feb 02 02:01:42 2010 +0200
@@ -0,0 +1,1462 @@
+// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include <escapeutils.h>
+#include <uri8.h>
+#include <uri16.h>
+#include <delimitedpath8.h>
+#include <delimitedpath16.h>
+#include <uriutilscommon.h>
+#include <uriutils.h>
+
+#include "UriUtilsInternal.h"
+#include "TUriCInternal.h"
+#include "CUriInternal.h"
+
+// Panic category
+//
+#ifdef _DEBUG
+	_LIT(KUriPanicCategory,"URI-CURI"); 
+#endif
+
+// Constants
+//
+_LIT(KFileUriPanicCategory,"FILEURI-CURI");
+
+
+
+
+//
+//
+// Implementation of CUri8
+//
+//
+
+/**
+	Static factory constructor. Uses two phase construction and leaves nothing on the 
+	CleanupStack. Creates a uri object which is a copy of the input parameter aUri.
+	
+	@since			6.0
+	@param			aUri	A reference to a parsed uri object.
+	@return			A pointer to the newly created CUri8 object. 
+	@post			A fully constructed and initialized CUri8 object.
+ */
+EXPORT_C CUri8* CUri8::NewL(const TUriC8& aUri)
+	{
+	CUri8* self = CUri8::NewLC(aUri);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**	
+	Static factory constructor. Uses two phase construction and leaves a pointer to 
+	created object on the CleanupStack. Creates a uri object which is a copy of the 
+	input parameter aUri.
+	
+	@since			6.0
+	@param			aUri	A reference to a parsed uri object.
+	@return			A pointer to the newly created CUri8 object. 
+	@post			A fully constructed and initialized CUri8 object.
+ */
+EXPORT_C CUri8* CUri8::NewLC(const TUriC8& aUri)
+	{
+	CUri8* self = new (ELeave) CUri8(aUri);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+	
+/**	
+	Static factory constructor. Uses two phase construction and leaves nothing on the 
+	CleanupStack. Creates a uri object which is empty.
+	
+	@since			6.0
+	@return			A pointer to the newly created CUri8 object. 
+	@post			A fully constructed and initialized CUri8 object.
+ */
+EXPORT_C CUri8* CUri8::NewL()
+	{
+	CUri8* self = CUri8::NewLC();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+	Static factory constructor. Uses two phase construction and leaves a pointer to created 
+	object on the CleanupStack. Creates a uri object which is empty.
+	
+	@since			6.0
+	@return			A pointer to the newly created CUri8 object. 
+	@post			A fully constructed and initialized CUri8 object.
+ */
+EXPORT_C CUri8* CUri8::NewLC()
+	{
+	CUri8* self = new (ELeave) CUri8(TUriC8());
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+/**	
+	Static factory constructor. This creates a CUri8 object that is an absolute uri resulting 
+	from a reference uri being resolved against a base uri.
+	
+	@warning		Ownership of created CUri8 object is transferred to the caller.
+	@leave			KUriErrBadBasePath if the base path is not an absolute path and not empty.
+	@since			6.0
+	@param			aBaseUri	A referece to the parsed base uri.
+	@param			aRefUri		A referece to the parsed reference uri.
+	@return			A pointer to the newly created CUri8 object.
+	@pre 			The base uri must have an absolute or empty path, otherwise will leave
+	with KUriErrBadBasePath.
+	@post			A fully constructed and initialized CUri8 object.
+ */
+EXPORT_C CUri8* CUri8::ResolveL(const TUriC8& aBaseUri, const TUriC8& aRefUri)
+	{
+	// Check for a base Uri
+	if( aBaseUri.UriDes().Compare(KNullDesC8) == 0 )
+		{
+		// Empty base Uri - resolved Uri is the reference Uri
+		return NewL(aRefUri);
+		}
+	// See if ref has scheme and it is the same as base Uri
+	if( aRefUri.IsPresent(EUriScheme) && (aRefUri.Compare(aBaseUri, EUriScheme) != 0) )
+		{
+		// Ref has a scheme different to base Uri's - it is an absolute Uri
+		return NewL(aRefUri);
+		}
+	// Check for presence of components
+	TBool useBaseQuery = EFalse;
+	HBufC8* resolvedPath = FormResolvedPathLC<HBufC8>(aBaseUri, aRefUri, useBaseQuery);
+
+	//Removes dot segemnts in Resolved uri as specified in RFC3986 section 5.2.
+	RemoveExtraneousDotSegmentsL(resolvedPath);
+	
+	// Put the Uri together
+	TUriC8 uri;
+	FormResolvedUri(uri.iComponent, aBaseUri, aRefUri, resolvedPath, useBaseQuery);
+
+	// Create the resolved Uri and cleanup
+	CUri8* resolvedUri = NewL(uri);
+	CleanupStack::PopAndDestroy(resolvedPath);
+
+	return resolvedUri;
+	}
+
+/**	
+	Destructor.
+	
+	@since			6.0
+ */
+EXPORT_C CUri8::~CUri8()
+	{
+	delete iUriBuf;
+	}
+
+/**	
+	Provides a reference to the parsed uri. Allows access to the non-modifying API for TUriC8.
+	
+	@since			6.0
+	@return			A const reference to the parsed uri object.
+ */
+EXPORT_C const TUriC8& CUri8::Uri() const
+	{
+	return iUri;
+	}
+
+/**	
+	Intended Usage	:	Sets the specified component in the uri. The component is set to the value 
+	given in the argument aData. If the specified component already exists  then it is replaced 
+	with the new value.
+	
+	@warning		The userinfo and port components can only be set if the host component
+	is present. Setting these components without a host component present will have no 
+	effect on the uri.
+	@since			6.0
+	@param			aData		A descriptor pointer to the new value for the uri component.
+	@param			aComponent	An enum specifying the component to be set.
+	@pre 			Object is fully constructed.
+	@post			The uri has the specified component set to the new value.
+	@Leave          KErrArgument  If aComponent goes out of range.
+ */
+EXPORT_C void CUri8::SetComponentL(const TDesC8& aData, TUriComponent aComponent)
+	{
+	// Update the appropriate component table entry
+	iUri.iComponent[aComponent].Set(aData);
+
+	// Copy to the buffer by forming the uri
+	FormUriL();
+	}
+
+/**	
+	Removes the specified component from the uri. If the component does not exist then this function 
+	does nothing.
+	
+	@warning		If host is removed, then userinfo and port components will also
+	be removed.
+	@since			6.0
+	@param			aComponent	An enum specifying the component to be removed.
+	@pre 			Object is fully constructed.
+	@post			The uri is updated to exclude the specified component.
+ */
+EXPORT_C void CUri8::RemoveComponentL(TUriComponent aComponent)
+	{
+	if( iUri.IsPresent(aComponent) )
+		{
+		// Remove the component - set pointer to NULL and length to zero
+		iUri.iComponent[aComponent].Set(NULL,0);
+
+		// Re-form buffer and component table
+		FormUriL();
+		}
+	}
+
+/**	
+	Constructor. First phase of two-phase construction method. Does	non-allocating construction.
+	
+	@since			6.0
+	@param			aUri	The parsed uri component information from which to create 
+	the uri.
+*/
+CUri8::CUri8(const TUriC8& aUri)
+: CBase(), iUri(aUri)
+	{
+	}
+
+/**	
+	Second phase of two-phase construction method. Does any allocations required to fully construct 
+	the object.
+	
+	@since			6.0
+	@pre 			First phase of construction is complete.
+	@post			The object is fully constructed and initialized.
+ */
+void CUri8::ConstructL()
+	{
+	// Create the HBufC
+	FormUriL();
+	}
+
+/**	
+	Forms the uri from the parsed uri information. A copy of the parsed uri is created. The parsed uri 
+	is changed to refer to the copy.
+	
+	@since			6.0
+	@pre 			The parsed uri information is set.
+	@post			The uri buffer is updated with the parsed uri information.
+ */
+void CUri8::FormUriL()
+	{
+	TBool isIPv6Host;
+
+	// Calculate length of of the Uri
+	TInt length = CalculateUriLength(iUri.iComponent, isIPv6Host);
+
+	// Create a temporary buffer and descriptor pointer to it
+	HBufC8* buf = HBufC8::NewL(length);
+	TPtr8 uri = buf->Des();
+
+	// Create the uri, updating the internal uri object
+	DoFormUri(uri, iUri.iComponent, isIPv6Host);
+
+	// Update the internal buffer and descriptor pointer
+	delete iUriBuf;
+	iUriBuf = buf;
+	iUri.iUriDes.Set(iUriBuf->Des());
+	}
+
+//
+//
+// Implementation of CUri16
+//
+//
+
+/**	
+	Static factory constructor. Uses two phase construction and leaves nothing on the CleanupStack. 
+	Creates a uri object which is a copy of the input parameter aUri.
+	
+	@deprecated Deprecated in 9.1
+	@since			6.0
+	@param			aUri	A reference to a parsed uri object.
+	@return			A pointer to the newly created CUri16 object. 
+	@post			A fully constructed and initialized CUri16 object.
+ */
+EXPORT_C CUri16* CUri16::NewL(const TUriC16& aUri)
+	{
+	CUri16* self = CUri16::NewLC(aUri);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**	
+	Static factory constructor. Uses two phase construction and leaves a pointer to created object on 
+	the CleanupStack. Creates a uri object which is a copy of the input parameter aUri.
+	
+	@since			6.0
+	@deprecated Deprecated in 9.1
+	@param			aUri	A reference to a parsed uri object.
+	@return			A pointer to the newly created CUri16 object. 
+	@post			A fully constructed and initialized CUri16 object.
+ */
+EXPORT_C CUri16* CUri16::NewLC(const TUriC16& aUri)
+	{
+	CUri16* self = new (ELeave) CUri16(aUri);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+/**
+	Static factory constructor. Uses two phase construction and leaves nothing on the CleanupStack. 
+	Creates a uri object which is empty.
+	
+	@since			6.0
+	@deprecated Deprecated in 9.1
+	@return			A pointer to the newly created CUri16 object. 
+	@post			A fully constructed and initialized CUri16 object.
+ */
+EXPORT_C CUri16* CUri16::NewL()
+	{
+	CUri16* self = CUri16::NewLC();
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+	Static factory constructor. Uses two phase construction and leaves a pointer to created object on 
+	the CleanupStack. Creates a uri object which is empty.
+	
+	@since			6.0
+	@deprecated Deprecated in 9.1
+	@return			A pointer to the newly created CUri16 object. 
+	@post			A fully constructed and initialized CUri16 object.
+ */
+EXPORT_C CUri16* CUri16::NewLC()
+	{
+	CUri16* self = new (ELeave) CUri16(TUriC16());
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return self;
+	}
+
+/**	
+	Static factory constructor. This creates a CUri16 object that is an absolute uri resulting from a 
+	reference uri being resolved against a base uri.
+	
+	@warning		Ownership of created CUri16 object is transferred to caller.
+	@leave			KUriErrBadBasePath if the base path is not an absolute path and not empty.
+	@since			6.0
+	@deprecated Deprecated in 9.1
+	@param			aBaseUri	A referece to the parsed base uri.
+	@param			aRefUri		A referece to the parsed reference uri.
+	@return			A pointer to the newly created CUri16 object.
+	@pre 			The base uri must have an absolute or empty path, otherwise will leave
+	with KUriErrBadBasePath.
+	@post			A fully constructed and initialized CUri16 object.
+ */
+EXPORT_C CUri16* CUri16::ResolveL(const TUriC16& aBaseUri, const TUriC16& aRefUri)
+	{
+	// Check for a base Uri
+	if( aBaseUri.UriDes().Compare(KNullDesC16) == 0 )
+		{
+		// Empty base Uri - resolved Uri is the reference Uri
+		return NewL(aRefUri);
+		}
+	// See if ref has scheme and it is the same as base Uri
+	if( aRefUri.IsPresent(EUriScheme) && aRefUri.Compare(aBaseUri, EUriScheme) != 0 )
+		{
+		// Ref has a scheme different to base Uri's - it is an absolute Uri
+		return NewL(aRefUri);
+		}
+	// Check for presence of components
+	TBool useBaseQuery = EFalse;
+	HBufC16* resolvedPath = FormResolvedPathLC<HBufC16>(aBaseUri, aRefUri, useBaseQuery);
+
+	// Put the Uri together
+	TUriC16 uri;
+	FormResolvedUri(uri.iComponent, aBaseUri, aRefUri, resolvedPath, useBaseQuery);
+
+	// Create the resolved Uri and cleanup
+	CUri16* resolvedUri = NewL(uri);
+	CleanupStack::PopAndDestroy(resolvedPath);
+
+	return resolvedUri;
+	}
+
+/**	
+	Destructor.
+	
+	@since			6.0
+	@deprecated Deprecated in 9.1
+ */
+EXPORT_C CUri16::~CUri16()
+	{
+	delete iUriBuf;
+	}
+
+/**	
+	Provides a reference to the parsed uri. Allows access to the non-modifying API for TUriC16.
+	
+	@since			6.0
+	@deprecated Deprecated in 9.1
+	@return			A const reference to the parsed uri object.
+ */
+EXPORT_C const TUriC16& CUri16::Uri() const
+	{
+	return iUri;
+	}
+
+/**
+	Sets the specified component in the uri. The component is set to the value given in the argument 
+	aData. If the specified component already exists then it is replaced with the new value.
+	
+	@warning		The userinfo and port components can only be set if the host component
+	is present. Setting these components without a host component present will have no 
+	effect on the uri.
+	@since			6.0
+	@deprecated Deprecated in 9.1
+	@param			aData		A descriptor pointer to the new value for the uri component.
+	@param			aComponent	An enum specifying the component to be set.
+	@pre 			Object is fully constructed.
+	@post			The uri has the specified component set to the new value.
+	@Leave          KErrArgument  If aComponent goes out of range.
+ */
+EXPORT_C void CUri16::SetComponentL(const TDesC16& aData, TUriComponent aComponent)
+	{
+	// Update the appropriate component table entry
+	iUri.iComponent[aComponent].Set(aData);
+
+	// Copy to the buffer by forming the uri
+	FormUriL();
+	}
+
+/**
+	Removes the specified component from the uri. If the component does not exist then this function 
+	does nothing.
+	
+	@warning		If host is removed, then userinfo and port components will also
+	be removed.
+	@since			6.0
+	@deprecated Deprecated in 9.1
+	@param			aComponent	An enum specifying the component to be removed.
+	@pre 			Object is fully constructed.
+	@post			The uri is updated to exclude the specified component.
+ */
+EXPORT_C void CUri16::RemoveComponentL(TUriComponent aComponent)
+	{
+	if( iUri.IsPresent(aComponent) )
+		{
+		// Remove the component - set pointer to NULL and length to zero
+		iUri.iComponent[aComponent].Set(NULL,0);
+
+		// Re-form buffer and component table
+		FormUriL();
+		}
+	}
+
+/**
+	Constructor. First phase of two-phase construction method. Does	non-allocating construction.
+	
+	@since			6.0
+	@param			aUri	The parsed uri component information from which to create
+	the uri.
+ */
+
+CUri16::CUri16(const TUriC16& aUri)
+: CBase(), iUri(aUri)
+	{
+	}
+
+/**
+	Second phase of two-phase construction method. Does any allocations required to fully construct 
+	the object.
+	
+	@since			6.0
+	@pre 			First phase of construction is complete.
+	@post			The object is fully constructed and initialized.
+ */
+void CUri16::ConstructL()
+	{
+	// Create the HBufC
+	FormUriL();
+	}
+
+/**
+	Forms the uri from the parsed uri information. A copy of the parsed uri is created. The parsed uri 
+	is changed to refer to the copy.
+	
+	@since			6.0
+	@pre 			The parsed uri information is set.
+	@post			The uri buffer is updated with the parsed uri information.
+ */
+void CUri16::FormUriL()
+	{
+	TBool isIPv6Host;
+
+	// Calculate length of of the Uri
+	TInt length = CalculateUriLength(iUri.iComponent, isIPv6Host);
+
+	// Create a temporary buffer and descriptor pointer to it
+	HBufC16* buf = HBufC16::NewL(length);
+	TPtr16 uri = buf->Des();
+
+	// Create the uri, updating the internal uri object
+	DoFormUri(uri, iUri.iComponent, isIPv6Host);
+
+	// Update the internal buffer and descriptor pointer
+	delete iUriBuf;
+	iUriBuf = buf;
+	iUri.iUriDes.Set(iUriBuf->Des());
+	}
+
+//
+//
+// Implementation of templated LOCAL functions
+//
+//
+
+/**
+	Calculates the length of the uri from a list of the components.
+	
+	@since			6.0
+	@param			aComponent	The array of descriptor pointers to the uri 
+					components.
+	@param			aIsIPv6Host	ETrue if an IPv6 format host is used
+	@return			The length of the uri including the required delimiters.	
+*/
+template<class TPtrCType>
+TInt CalculateUriLength(const TPtrCType aComponent[], TBool& aIsIPv6Host)
+	{
+	TBool noAuthority = ETrue;
+	TInt length=0;
+	aIsIPv6Host=EFalse;
+	for( TInt i=0; i<EUriMaxComponents; ++i )
+		{
+		if( aComponent[i].Ptr() )
+			{
+			length += aComponent[i].Length();
+			if( noAuthority && (i==EUriUserinfo || i==EUriHost || i==EUriPort) )
+				{
+				// There's an authority part...
+				noAuthority = EFalse;
+				}
+			// Need to make space for a delimiter if not path or host
+			if( i!=EUriHost && i!=EUriPath )
+				++length;		
+			
+			// If it's an IPv6 hostname, need extra space for []
+			if(i==EUriHost && (UriUtils::HostType(aComponent[i])==UriUtils::EIPv6Host))
+				{
+				length+=2;				
+				aIsIPv6Host=ETrue;
+				}
+			}
+		}
+	if( !noAuthority && IsNetworkScheme(aComponent[EUriScheme]))
+		{
+		// Make space for authority delimiter
+		length += KUriNetworkAuthorityDelimiterLength;
+		}
+	return length;
+	}
+
+/**
+	Templated function to form a uri. The output argument aUri points to a descriptor 
+	buffer large enough to hold the uri. The new uri component information is given by 
+	the input/output argument aComponent. For each uri component that exists in aComponent,
+	that component and its appropriate delimiters are appended to aUri. Then the components 
+	in aComponent are updated to refer to the copies versions in aUri.
+						
+	@since			6.0
+	@param			aUri		The descriptor pointer to buffer to be appended.
+	@param			aComponent	The array of descriptor pointers to be copied and 
+					then updated.
+	@param			aIsIPv6Host	ETrue if an IPv6 format host is used
+	@pre 			The buffer pointed to by aUri should be large enough to have the uri 
+					components given in aNewComponent copied into it, as well as the required delimiters.
+					This can be obtained using CalculateUriLength().
+	@post			The uri buffer pointed to by aUri will have a copy of the uri defined 
+					in aComponent, and then aComponent will refer to the copies of these components in aUri.
+*/
+template<class TPtrType, class TPtrCType>
+void DoFormUri(TPtrType& aUri, TPtrCType aComponent[], TBool& aIsIPv6Host)
+	{
+	TBool isNetworkScheme = ETrue;
+	if( aComponent[EUriScheme].Ptr() )
+		{
+		// Update the scheme
+		SetScheme(aUri, aComponent[EUriScheme]);
+		isNetworkScheme = IsNetworkScheme(aComponent[EUriScheme]);
+		}
+	if( aComponent[EUriHost].Ptr() )
+		{
+		// Update the authority - only needed if there is a host; update userinfo, host and port
+		SetAuthority(aUri, aComponent[EUriUserinfo], aComponent[EUriHost], aComponent[EUriPort], aIsIPv6Host, isNetworkScheme);
+		}
+	else
+		{
+		// Ensure that there is no userinfo or port components if there is no host 
+		// - set pointer to NULL and length to zero
+		aComponent[EUriUserinfo].Set(NULL,0);
+		aComponent[EUriPort].Set(NULL,0);
+		}
+	if( aComponent[EUriPath].Ptr() )
+		{
+		// Update the path
+		SetPath(aUri, aComponent[EUriPath]);
+		}
+	if( aComponent[EUriQuery].Ptr() )
+		{
+		// Update the query
+		SetQuery(aUri, aComponent[EUriQuery]);
+		}
+	if( aComponent[EUriFragment].Ptr() )
+		{
+		// Update the fragment
+		SetFragment(aUri, aComponent[EUriFragment]);
+		}
+	}
+
+/**
+	Templated function to set the scheme in a uri. The output argument aUri points to the descriptor 
+	buffer into which aScheme will be copied.The argument aScheme is then updated to point to the 
+	copied version in aUri.
+						
+	@warning		This function will panic with KUriErrBufferOverflow if there is not
+					enough space in the descriptor to append the scheme and the required delimiter.
+	@since			6.0
+	@param			aUri	The descriptor pointer to buffer to be appended.
+	@param			aScheme	The descriptor pointer to the scheme component to be copied 
+					and then updated.
+	@pre 			The buffer pointed to by aUri should be large enough to have aNewScheme
+					appended to it with the required delimiter. This can be obtained using CalculateUriLength().
+	@post			The uri buffer now includes a copy of aScheme and aScheme points to the 
+					copy of the scheme component in aUri.
+*/
+template<class TPtrType, class TPtrCType>
+void SetScheme(TPtrType& aUri, TPtrCType& aScheme)
+	{
+	__ASSERT_DEBUG(aUri.Length() + aScheme.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
+
+	// Append the scheme and delimiter
+	aUri.Append(aScheme);
+	aUri.Append(KSchemeDelimiter);
+
+	// Update the component table to use the copy
+	aScheme.Set(aUri.Left(aScheme.Length()));
+	}
+	
+/**
+	Templated function to set the authority in a uri. The output argument aUri points to the descriptor 
+	buffer into which aUserinfo, aHost and aPort will be copied. The arguments aUserinfo, aHost and aPort 
+	are updated to point to the copied versions in aUri.
+						
+	@warning		This function will panic with KUriErrBufferOverflow if there 
+					is not enough space in the descriptor to append the components and any required 
+					delimiters. 
+	@since			6.0
+	@param			aUri		The descriptor pointer to buffer to be appended.
+	@param			aUserinfo	The descriptor pointer to the userinfo component to 
+					be copied and then updated.
+	@param			aHost		The descriptor pointer to the host component to 
+					be copied and then updated.
+	@param			aPort		The descriptor pointer to the port component to 
+					be copied and then updated.
+	@param			aIsIPv6Host	ETrue if an IPv6 format host is used
+	@param			aUseNetworkDelimiter EFalse if this is a SIP scheme otherwise ETrue
+	@pre 			The buffer pointed to by aUri should be large enough to have 
+					aUserinfo, aHost and aPort appended to it with the required delimiters.
+					This can be obtained using CalculateUriLength().
+	@post			The uri buffer now includes a copy of aUserinfo, aHost and
+					aPort, and aUserinfo, aHost and aPort will refer to the copies versions in aUri.
+*/
+template<class TPtrType, class TPtrCType>
+void SetAuthority(TPtrType& aUri, TPtrCType& aUserinfo, TPtrCType& aHost, TPtrCType& aPort, TBool& aIsIPv6Host, TBool aUseNetworkDelimiter)
+	{
+	__ASSERT_DEBUG(aUri.Length() + aHost.Length() + (aUseNetworkDelimiter ? KUriNetworkAuthorityDelimiterLength:0) <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
+	
+	if (aUseNetworkDelimiter)
+		{
+		// If a network scheme append authority delimiter (TWO slash delimiters!)
+		aUri.Append(KSlashDelimiter);
+		aUri.Append(KSlashDelimiter);
+		}
+
+	// Check for userinfo
+	if( aUserinfo.Ptr() )
+		{
+		__ASSERT_DEBUG(aUri.Length() + aUserinfo.Length() + aHost.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
+
+		// Append userinfo and update the component table to use copy
+		aUri.Append(aUserinfo);
+		aUserinfo.Set(aUri.Right(aUserinfo.Length()));
+
+		// Append delimiter
+		aUri.Append(KUserinfoDelimiter);
+		}
+	// There's always a host - append and update the component table to use the copy
+	
+	// Check if it's an IPv6 address
+	if ( aIsIPv6Host )
+		{
+		aUri.Append(KIPv6UriOpenBrace); 
+		aUri.Append(aHost);
+		aUri.Append(KIPv6UriCloseBrace);
+		// Dont include the braces in the host
+		// Position = (length of uri - length of host) - length of end brace
+		aHost.Set( aUri.Mid((aUri.Length()-aHost.Length())-1, aHost.Length()) );
+		}
+	else
+		{
+		aUri.Append(aHost);
+		aHost.Set(aUri.Right(aHost.Length()));
+		}
+	
+	// Check for a port
+	if( aPort.Ptr() )
+		{
+		__ASSERT_DEBUG(aUri.Length() + aPort.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
+				   
+		// Append delimiter
+		aUri.Append(KPortDelimiter);
+	
+		// Append port and update the component table to use copy
+		aUri.Append(aPort);
+		aPort.Set(aUri.Right(aPort.Length()));
+		}
+	}
+/**
+	Templated function to set the path in a uri. The output argument aUri points to the descriptor 
+	buffer into which aPath will be copied.The argument aPath is then updated to point to the copied 
+	version in aUri.
+						
+	@warning		This function will panic with KUriErrBufferOverflow if there 
+					is not enough space in the descriptor to append the path.
+	@since			6.0
+	@param			aUri	The descriptor pointer to buffer to be appended.
+	@param			aPath	The descriptor pointer to the path component to be copied 
+					and then updated.
+	@pre 			The buffer pointed to by aUri should be large enough to have 
+					aPath appended to it. This can be obtained using CalculateUriLength().
+	@post			The uri buffer now includes a copy of aPath and aPath points to the 
+					copy of the path component in aUri.
+*/
+template<class TPtrType, class TPtrCType>
+void SetPath(TPtrType& aUri, TPtrCType& aPath)
+	{
+	__ASSERT_DEBUG(aUri.Length() + aPath.Length() <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
+
+	// Append the path
+	aUri.Append(aPath);
+
+	// Update the component table
+	aPath.Set(aUri.Right(aPath.Length()));
+	}
+
+/**
+	Templated function to set the query in a uri. The output argument aUri points to the descriptor 
+	buffer into which aQuery will be copied. The argument aQuery is then updated to point to the copied 
+	version in aUri.
+						
+	@warning		This function will panic with KUriErrBufferOverflow if there 
+					is not enough space in the descriptor to append the query and the delimiter.
+	@since			6.0
+	@param			aUri	The descriptor pointer to buffer to be appended.
+	@param			aQuery	The descriptor pointer to the query component to be copied 
+					and then updated.
+	@pre 			The buffer pointed to by aUri should be large enough to have 
+					aQuery appended to it. This can be obtained using CalculateUriLength().
+	@post			The uri buffer now includes a copy of aQuery and aQuery points to the 
+					copy of the query component in aUri.
+*/
+template<class TPtrType, class TPtrCType>
+void SetQuery(TPtrType& aUri, TPtrCType& aQuery)
+	{
+	__ASSERT_DEBUG(aUri.Length() + aQuery.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
+
+	// Append delimiter and the query
+	aUri.Append(KQueryDelimiter);
+	aUri.Append(aQuery);
+
+	// Update the component table
+	aQuery.Set(aUri.Right(aQuery.Length()));
+	}
+
+/**
+	Templated function to set the fragment in a uri. The output argument aUri points to the descriptor 
+	buffer into which aFragment will be copied. The argument aFragment is then updated to point to the 
+	copied version in aUri.
+						
+	@warning		This function will panic with KUriErrBufferOverflow if there 
+					is not enough space in the descriptor to append the fragment and the delimiter.
+	@since			6.0
+	@param			aUri		The descriptor pointer to buffer to be appended.
+	@param			aFragment	The descriptor pointer to the fragment component
+					to be copied and then updated.
+	@pre 			The buffer pointed to by aUri should be large enough to have 
+					aFragment appended to it. This can be obtained using CalculateUriLength().
+	@post			The uri buffer now includes a copy of aFragment and aFragment points 
+					to the copy of the fragment component in aUri.
+*/
+template<class TPtrType, class TPtrCType>
+void SetFragment(TPtrType& aUri, TPtrCType& aFragment)
+	{
+	__ASSERT_DEBUG(aUri.Length() + aFragment.Length() + 1 <= aUri.MaxLength(), User::Panic(KUriPanicCategory, KUriUtilsErrBufferOverflow));
+
+	// Append delimiter and the fragment
+	aUri.Append(KFragmentDelimiter);
+	aUri.Append(aFragment);
+
+	// Update the component table
+	aFragment.Set(aUri.Right(aFragment.Length()));
+	}
+
+/**
+	Forms the resolved path. Checks to see if the base query needs to be used in the resolved uri. 
+	The pointer to the resolved path is left on the cleanup stack.
+						
+	@since			6.0
+	@param			aBaseUri		The base uri.
+	@param			aRefUri			The reference uri.
+	@param			aUseBaseQuery	An output argument specifying whether the base
+					query should be used in the resolved uri.
+	@return			A pointer to a buffer that contains the resolved path.
+*/
+template<class HBufCType, class TUriCType>
+HBufCType* FormResolvedPathLC(const TUriCType& aBaseUri, const TUriCType& aRefUri, TBool& aUseBaseQuery)
+	{
+	HBufCType* resolvedPath = NULL;
+	if( !aRefUri.IsPresent(EUriScheme) && !aRefUri.IsPresent(EUriHost) && !aRefUri.Extract(EUriPath).Length() && !aRefUri.IsPresent(EUriQuery) )
+		{
+		// Ref is just a fragment
+		aUseBaseQuery = ETrue;
+		resolvedPath = aBaseUri.Extract(EUriPath).AllocLC();
+		}
+	else if( aRefUri.IsPresent(EUriHost) )
+		{
+		// Ref is a network path
+		resolvedPath = aRefUri.Extract(EUriPath).AllocLC();
+		}
+	else
+		{
+		// Need to some path resolving...
+		resolvedPath = ResolvePathsL(aBaseUri.Extract(EUriPath), aRefUri.Extract(EUriPath));
+		CleanupStack::PushL(resolvedPath);
+		}
+	return resolvedPath;
+	}
+
+/**
+	Cleans up a resolved path. This deals with occurences of '.' and '..' where these are complete 
+	path segments.
+						
+	@since			6.0
+	@param			aResolvedPath	The delimited data object that contains the 
+					resolved path.
+	@pre 			The input/output argument contains the path to be cleaned.
+	@post			The resolved path has had all the occurences of '.' and '..' 
+					processed and has been updated to contain the cleaned path.
+ */
+template<class TPtrCType, class CDelimitedDataBaseType>
+void CleanResolvedPathL(CDelimitedDataBaseType* aResolvedPath)
+	{
+	// Create a modifiable path object for resolved path
+	aResolvedPath->Parse();
+
+	TBool done = EFalse;
+	while( !done )
+   		{
+   		// Get the next segment
+   		TPtrCType segment;
+   		TInt more = aResolvedPath->Parser().Peek(segment);
+
+   		if( more == KErrNotFound )
+   			{
+   			// No more segments - done
+   			done = ETrue;
+   			}
+   		else if( IsParentDir(segment) )
+   			{
+   			// Found a '..' - remove '..' from path, and remove previous segment
+			aResolvedPath->RemoveCurrentL();
+			if( aResolvedPath->Parser().Dec() == KErrNotFound )
+				{
+				// No previous directory - put back '..' and stop
+				InsertParentDirL(aResolvedPath);
+				done = ETrue;
+				}
+			else
+				{
+				// Remove the parent directory
+				aResolvedPath->RemoveCurrentL();
+				if( aResolvedPath->Parser().Eos() )
+					{
+					// '..' is the last segment - add a '/' to the path (add empty segment)
+					aResolvedPath->AddBackDelimiterL();
+					done = ETrue;
+					}
+				}
+			}
+   		else if( IsSameDir(segment) )
+   			{
+   			// Found a '.' - remove -.- from the path
+			aResolvedPath->RemoveCurrentL();
+			if( aResolvedPath->Parser().Eos() )
+				{
+				// '..' is the last segment - add a '/' to the path (add empty segment)
+				aResolvedPath->AddBackDelimiterL();
+				done = ETrue;
+				}
+			}
+   		else
+   			{
+   			// Segment wasn't '.' or '..' - parse to next segment
+   			aResolvedPath->Parser().Inc();
+   			}
+   		}
+	}
+
+/**
+	Forms the resolved uri. Sets the components for the resolved uri from those in the base uri and 
+	the reference uri. The resolved path is given by the input argument aResolvedPath
+						
+	@since			6.0
+	@param			aComponent		The array of components to be set for the resolved uri.
+	@param			aBaseUri		The base uri.
+	@param			aRefUri			The reference uri.
+	@param			aResolvedPath	The resolved path.
+	@param			aUseBaseQuery	A boolean indicating whether the base query 
+					should be used.
+*/
+template<class TPtrCType, class TUriCType, class HBufCType>
+void FormResolvedUri(TPtrCType aComponent[], const TUriCType& aBaseUri, const TUriCType& aRefUri, const HBufCType* aResolvedPath, TBool aUseBaseQuery)
+	{
+	// Scheme...
+	if( aBaseUri.IsPresent(EUriScheme) )
+		{
+		// Use the base scheme
+		aComponent[EUriScheme].Set(aBaseUri.Extract(EUriScheme));
+		}
+	// Authority
+	if( aRefUri.IsPresent(EUriHost) )
+		{
+		// Use the ref host, userinfo and port - must set host first
+		aComponent[EUriHost].Set(aRefUri.Extract(EUriHost));
+		aComponent[EUriUserinfo].Set(aRefUri.Extract(EUriUserinfo));
+		aComponent[EUriPort].Set(aRefUri.Extract(EUriPort));
+		}
+	else if( aBaseUri.IsPresent(EUriHost) )
+		{
+		// Use the base host, userinfo and port - must set host first
+		aComponent[EUriHost].Set(aBaseUri.Extract(EUriHost));
+		aComponent[EUriUserinfo].Set(aBaseUri.Extract(EUriUserinfo));
+		aComponent[EUriPort].Set(aBaseUri.Extract(EUriPort));
+		}
+	// Path...
+	aComponent[EUriPath].Set(*aResolvedPath);
+
+	// Query...
+	if( aUseBaseQuery && aBaseUri.IsPresent(EUriQuery) )
+		{
+		// Use the query from the base
+		aComponent[EUriQuery].Set(aBaseUri.Extract(EUriQuery));
+		}
+	else if( aRefUri.IsPresent(EUriQuery) )
+		{
+		// Use the query from the ref
+		aComponent[EUriQuery].Set(aRefUri.Extract(EUriQuery));
+		}
+	// Fragment
+	if( aRefUri.IsPresent(EUriFragment) )
+		{
+		// Use the fragment from the ref
+		aComponent[EUriFragment].Set(aRefUri.Extract(EUriFragment));
+		}
+	}
+
+//
+//
+// Implemetation of LOCAL functions
+//
+//
+
+/**
+	Function used to resolve a base path (aBasePath) against a reference path (aRefPath),
+	as described by RFC2396.
+						
+	@since			6.0
+	@param			aBasePath	A descriptor reference to the base path.
+	@param			aRefPath	A descriptor reference to the reference path.
+	@return			A pointer to a buffer containing the resolve path.
+	@leave			KUriErrBadBasePath if the base path is not an absolute path and not empty.
+*/
+HBufC8* ResolvePathsL(const TDesC8& aBasePath, const TDesC8& aRefPath)
+	{
+	TInt refLength = aRefPath.Length();
+	if( refLength && aRefPath[0] == KSlashDelimiter )
+		{
+		// Relative path is absolute - that is the resolved path
+		return aRefPath.AllocL();
+		}
+	// Ok got work to do - base path must be absolute (check 1st char) or empty
+	if( aBasePath.Length() && aBasePath[0] != KSlashDelimiter )
+		{
+		// Base path not empty and not abosolute - bad base path
+		User::Leave(KUriUtilsErrBadBasePath);
+		}
+	// Create a modifiable path object for resolved path
+	CDelimitedPath8* resolvedPath = CDelimitedPath8::NewLC(aBasePath);
+
+	// Check for empty ref path - use all of base path if empty
+	if( refLength )
+		{
+		// Not empty - ensure that base path's last segment is removed and add reference
+		resolvedPath->PopBackL();
+		resolvedPath->PushBackL(aRefPath);
+		}
+	// Clean up the path to resolve occurences of '..' and '.' - parser path first
+	CleanResolvedPathL<TPtrC8>(resolvedPath);
+
+	// Return pointer to HBufC with path
+	HBufC8* path = resolvedPath->Parser().Des().AllocL();
+	CleanupStack::PopAndDestroy(resolvedPath);
+	return path;
+	}
+
+/**
+	Function used to resolve a base path (aBasePath) against a reference path (aRefPath), 
+	as described by RFC2396.
+						
+	@since			6.0
+	@param			aBasePath	A descriptor reference to the base path.
+	@param			aRefPath	A descriptor reference to the reference path.
+	@return			A pointer to a buffer containing the resolve path.
+	@leave			KUriErrBadBasePath if the base path is not an absolute path and not empty.
+*/
+HBufC16* ResolvePathsL(const TDesC16& aBasePath, const TDesC16& aRefPath)
+	{
+	TInt refLength = aRefPath.Length();
+	if( refLength && aRefPath[0] == KSlashDelimiter )
+		{
+		// Relative path is absolute - that is the resolved path
+		return aRefPath.AllocL();
+		}
+	// Ok got work to do - base path must be absolute (check 1st char) or empty
+	if( aBasePath.Length() && aBasePath[0] != KSlashDelimiter )
+		{
+		// Base path not empty and not abosolute - bad base path
+		User::Leave(KUriUtilsErrBadBasePath);
+		}
+	// Create a modifiable path object for resolved path
+	CDelimitedPath16* resolvedPath = CDelimitedPath16::NewLC(aBasePath);
+
+	// Check for empty ref path - use all of base path if empty
+	if( refLength )
+		{
+		// Not empty - ensure that base path's last segment is removed and add reference
+		resolvedPath->PopBackL();
+		resolvedPath->PushBackL(aRefPath);
+		}
+	// Clean up the path to resolve occurences of '..' and '.' - parser path first
+	CleanResolvedPathL<TPtrC16>(resolvedPath);
+
+	// Return pointer to HBufC with path
+	HBufC16* path = resolvedPath->Parser().Des().AllocL();
+	CleanupStack::PopAndDestroy(resolvedPath);
+	return path;
+	}
+	
+/**
+	Checks if the segment is '.' (8-bit version).
+	
+	@since			6.0
+	@param			aSegment	A descriptor with the segment to check.
+	@return			A boolean value of ETrue if the segment is '.', EFalse if not.
+*/
+TBool IsSameDir(const TDesC8& aSegment)
+	{
+	_LIT8(KSameDir, ".");
+	return (aSegment.Compare(KSameDir) == 0);
+	}
+	
+/**
+	Checks if the segment is '.' (16-bit version).
+	
+	@since			6.0
+	@param			aSegment	A descriptor with the segment to check.
+	@return			A boolean value of ETrue if the segment is '.', EFalse if not.
+*/
+TBool IsSameDir(const TDesC16& aSegment)
+	{
+	_LIT16(KSameDir, ".");
+	return (aSegment.Compare(KSameDir) == 0);
+	}
+	
+/**
+	Checks if the segment is '..' (8-bit version).
+	
+	@since			6.0
+	@param			aSegment	A descriptor with the segment to check.
+	@return			A boolean value of ETrue if the segment is '..', EFalse if not.
+*/
+TBool IsParentDir(const TDesC8& aSegment)
+	{
+	_LIT8(KParentDir, "..");
+	return (aSegment.Compare(KParentDir) == 0);
+	}
+
+/**
+	Checks if the segment is '..' (16-bit version).
+	
+	@since			6.0
+	@param			aSegment	A descriptor with the segment to check.
+	@return			A boolean value of ETrue if the segment is '..', EFalse if not.
+*/
+TBool IsParentDir(const TDesC16& aSegment)
+	{
+	_LIT16(KParentDir, "..");
+	return (aSegment.Compare(KParentDir) == 0);
+	}
+
+/**
+	Inserts the segment '..' at the current parsed position (8-bit version).
+						
+	@since			6.0
+	@param			aResolvedPath	The delimited data object to have the segment
+					inserted.
+	@pre			The delimited data object must be parsed to the position where 
+					the segment is to be inserted.
+	@post			The segment '..' has been inserted at the current position.
+*/
+void InsertParentDirL(CDelimitedDataBase8* aResolvedPath)
+	{
+	_LIT8(KParentDir, "..");
+	aResolvedPath->InsertCurrentL(KParentDir);
+	}
+	
+/**
+	Inserts the segment '..' at the current parsed position (16-bit version).
+						
+	@since			6.0
+	@param			aResolvedPath	The delimited data object to have the segment
+					inserted.
+	@pre			The delimited data object must be parsed to the position where 
+					the segment is to be inserted.
+	@post			The segment '..' has been inserted at the current position.
+*/
+void InsertParentDirL(CDelimitedDataBase16* aResolvedPath)
+	{
+	_LIT16(KParentDir, "..");
+	aResolvedPath->InsertCurrentL(KParentDir);
+	}
+	
+
+//
+//
+// File URI Implementation - CUri8
+//
+//
+
+/**
+	Initializes the file URI components (scheme, empty hostname and path).	 
+	
+	It uses GenerateFileUriPathL() to generate a file Uri path using the filename and drive. 
+	
+	@since			9.1
+	@param			aFileName	A reference to a filename 
+	@param			aDrive		A drive number. This is a TFileUriFlags value.
+	@param			aFlags		A flag to indicate if the file exists on a fixed drive or removable media drive.
+					This is a TFileUriFlags value.
+	@pre 			Object fully constructed
+	@post			The object is initialized with file URI components.
+ */
+void CUri8::InitializeFileUriComponentsL(const TDesC& aFileName, TDriveNumber aDrive, TUint aFlags)
+	{
+	HBufC* uriPath16 = GenerateFileUriPathL(aFileName, aDrive, aFlags);
+	CleanupStack::PushL(uriPath16);
+	HBufC8* uriPath = EscapeUtils::ConvertFromUnicodeToUtf8L(*uriPath16);
+	CleanupStack::PopAndDestroy(uriPath16);
+	CleanupStack::PushL(uriPath);
+	HBufC8* escpedUriPath = EscapeUtils::EscapeEncodeL(*uriPath, EscapeUtils::EEscapeNormal);
+	CleanupStack::PopAndDestroy(uriPath);
+	CleanupStack::PushL(escpedUriPath);
+	
+	//SetComponent is not used in order to increase efficiency, by avoiding overhead of length calculation, 
+	//tmp buffer allocation and updation of internal uri object, internal buffer & descriptor pointer 
+	//for each SetComponent call     
+	iUri.iComponent[EUriPath].Set(*escpedUriPath);
+	iUri.iComponent[EUriHost].Set(KNullDesC8);
+	iUri.iComponent[EUriScheme].Set(KFileUriScheme8);
+	FormUriL();
+	
+	CleanupStack::PopAndDestroy(escpedUriPath);
+	}
+
+/**
+	Allocates and constructs a file URI object for a specified file.
+	 
+	- If the file exists on a fixed drive, then the file URI takes the form: 'file://\<drive-letter\>/\<filepath including filename\>'.	
+	- If the file exists on a removable media drive, then the file URI takes the form: 'file://ext-media/\<filepath including filename\>'.
+	
+	@since			9.1
+	@param			aFullFileName	A reference to a fully qualified filename 
+	@param			aFlags			A flag to indicate if the file exists on a fixed drive or removable media drive.
+									This is a TFileUriFlags value.
+	@return			A pointer to the newly created file URI (CUri8) object. 
+	@post			A fully constructed and initialized file URI (CUri8) object.
+ */
+EXPORT_C CUri8* CUri8::CreateFileUriL(const TDesC& aFullFileName, TUint aFlags)
+	{
+	//It should be called to construct a file URI for a public file stored on a fix drive 
+	// or on a removable media drive only
+	__ASSERT_ALWAYS( ((aFlags == 0) || (aFlags & EExtMedia)), User::Panic(KFileUriPanicCategory, KUriUtilsCannotConvert) );
+		
+	CUri8* self = CUri8::NewLC();
+	self->InitializeFileUriComponentsL(aFullFileName, EDriveA, aFlags);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+/**
+	Allocates and constructs a file URI object for a file that is private to the application.
+
+	- If the file exists on a fixed drive, then the file URI takes the form 'file://private/\<drive-letter\>/<filepath including filename\>'.
+	- If the file exists on a removable media drive, then the file URI takes the form 'file://private/ext-media/\<filepath including filename\>'.
+	
+	@since			9.1
+	@param			aRelativeFileName	A reference to the filename relative to the application's private directory.
+	@param			aDrive				Drive number, if the private file stored on fixed drive, otherwise not used
+										This is a TDriveNumber value
+	@param			aFlags				A flag to indicate if the file exists on a fixed drive or removable media drive.
+										This is a TFileUriFlags value.
+	@return			A pointer to the newly created file URI (CUri8) object. 
+	@post			A fully constructed and initialized file URI (CUri8) object.
+*/	
+
+
+EXPORT_C CUri8* CUri8::CreatePrivateFileUriL(const TDesC& aRelativeFileName, TDriveNumber aDrive, TInt aFlags) 
+	{
+	//It should be called to construct a file URI for the application's private file stored on a fix drive 
+	// or on a removable media drive only
+	__ASSERT_ALWAYS( (((aFlags == 0) || (aFlags & EExtMedia)) && (aDrive >= EDriveA && aDrive <= EDriveZ)), User::Panic(KFileUriPanicCategory, KUriUtilsCannotConvert) );
+
+	CUri8* self = CUri8::NewLC();
+	self->InitializeFileUriComponentsL(aRelativeFileName, aDrive, aFlags|EPrivate);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+//
+//
+// File URI Implementation - CUri16
+//
+//
+
+/**
+	Initializes the file URI components (scheme, empty hostname and path).	 
+	
+	It uses GenerateFileUriPathL() to generate a file Uri path using the filename and drive. 
+	
+	@since			9.1
+	@param			aFileName	A reference to a filename 
+	@param			aDrive		A drive number. This is a TFileUriFlags value.
+	@param			aFlags		A flag to indicate if the file exists on a fixed drive or removable media drive.
+					This is a TFileUriFlags value.
+	@pre 			Object fully constructed
+	@post			The object is initialized with file URI components.
+ */
+void CUri16::InitializeFileUriComponentsL(const TDesC& aFileName, TDriveNumber aDrive, TUint aFlags)
+	{	
+	HBufC* uriPath = GenerateFileUriPathL(aFileName, aDrive, aFlags);
+	CleanupStack::PushL(uriPath);
+
+	HBufC8* uriPath8 = EscapeUtils::ConvertFromUnicodeToUtf8L(*uriPath);
+	CleanupStack::PopAndDestroy(uriPath);
+	CleanupStack::PushL(uriPath8);
+
+	HBufC8* escapedUriPath8 = EscapeUtils::EscapeEncodeL(*uriPath8, EscapeUtils::EEscapeNormal);
+	CleanupStack::PopAndDestroy(uriPath8);
+	CleanupStack::PushL(escapedUriPath8);
+
+	HBufC* escapedUriPath = HBufC::NewLC(escapedUriPath8->Length());
+	escapedUriPath->Des().Copy(*escapedUriPath8); 
+	
+	//SetComponent is not used in order to increase efficiency, by avoiding overhead of length calculation, 
+	//tmp buffer allocation and updation of internal uri object, internal buffer & descriptor pointer 
+	//for each SetComponent call     
+	iUri.iComponent[EUriPath].Set(*escapedUriPath);
+	iUri.iComponent[EUriHost].Set(KNullDesC16);
+	iUri.iComponent[EUriScheme].Set(KFileUriScheme16);
+	FormUriL();
+	
+	CleanupStack::PopAndDestroy(escapedUriPath);
+	CleanupStack::PopAndDestroy(escapedUriPath8);
+	}
+
+/**
+	Allocates and constructs a file URI object for a specified file.
+	 
+	- If the file exists on a fixed drive, then the file URI takes the form: 'file://\<drive-letter\>/\<filepath including filename\>'.	
+	- If the file exists on a removable media drive, then the file URI takes the form: 'file://ext-media/\<filepath including filename\>'.
+	
+	@since			9.1
+	@param			aFullFileName	A reference to a fully qualified filename 
+	@param			aFlags	A flag to indicate if the file exists on a fixed drive or removable media drive.
+					This is a TFileUriFlags value.
+	@return			A pointer to the newly created file URI (CUri16) object. 
+	@post			A fully constructed and initialized file URI (CUri16) object.
+ */
+EXPORT_C CUri16* CUri16::CreateFileUriL(const TDesC& aFullFileName, TUint aFlags)
+	{
+	//It should be called to construct a file URI for a public file stored on a fix drive 
+	// or on a removable media drive only
+	__ASSERT_ALWAYS( ((aFlags == 0) || (aFlags & EExtMedia)), User::Panic(KFileUriPanicCategory, KUriUtilsCannotConvert) );
+		
+	CUri16* self = CUri16::NewLC();
+	self->InitializeFileUriComponentsL(aFullFileName, EDriveA, aFlags);
+	CleanupStack::Pop(self);
+	return self;
+	}
+	
+/**
+	Allocates and constructs a file URI object for a file that is private to the application.
+
+	- If the file exists on a fixed drive, then the file URI takes the form 'file://private/\<drive-letter\>/<filepath including filename\>'.
+	- If the file exists on a removable media drive, then the file URI takes the form 'file://private/ext-media/\<filepath including filename\>'.
+	
+	@since			9.1
+	@param			aRelativeFileName	A reference to the filename relative to the application's private directory.
+	@param			aDrive				Drive number, if the private file stored on fixed drive, otherwise not used
+										This is a TDriveNumber value
+	@param			aFlags				A flag to indicate if the file exists on a fixed drive or removable media drive.
+										This is a TFileUriFlags value.
+	@return			A pointer to the newly created file URI (CUri16) object. 
+	@post			A fully constructed and initialized file URI (CUri16) object.
+*/
+
+
+EXPORT_C CUri16* CUri16::CreatePrivateFileUriL(const TDesC& aRelativeFileName, TDriveNumber aDrive, TInt aFlags) 
+	{
+	//It should be called to construct a file URI for the application's private file stored on a fix drive 
+	// or on a removable media drive only
+	__ASSERT_ALWAYS( (((aFlags == 0) || (aFlags & EExtMedia)) && (aDrive >= EDriveA && aDrive <= EDriveZ)), User::Panic(KFileUriPanicCategory, KUriUtilsCannotConvert) );
+
+	CUri16* self = CUri16::NewLC();
+	self->InitializeFileUriComponentsL(aRelativeFileName, aDrive, aFlags|EPrivate);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+
+//
+//
+// Implemetation of LOCAL functions for the File URI
+//
+//
+	
+/**
+	Function used to generate 16bit file uri using 1st parameter aFileName and 
+	2nd parameter aDrive for the application's private or a public file.
+	
+	This is called by API CreateFileUri() and CreatePrivateFileUri()to 
+	generate a filename.
+	
+	Note: The space allocated for the returned descriptor will likely be larger 
+		  than the length of the descriptor
+	
+	@leave			KErrBadName	A provided Drivename or filename is not valid 
+	@since			9.1
+	@param			aFileName	A descriptor reference to the filename.
+	@param			aDrive		A descriptor reference to drive letter.
+	@param			aFlags		A flag to indicate the private or a public file exists on removable media or a fixed drive.
+	@return			A pointer to a buffer containing the resolved fully qualified filename.
+ */
+HBufC* GenerateFileUriPathL(const TDesC& aFileName, TDriveNumber aDrive,  TUint aFlags)
+	{
+	TInt origLength = aFileName.Length();
+
+	//Leaves with KErrBadName if filename length is out of range 
+	if (origLength == 0 || origLength > KMaxFileName)
+		{
+		User::Leave(KErrBadName);	
+		}
+		
+	TPtrC filename(aFileName);
+	
+	//extract drive letter and remove drive "x:" from filename
+	TUint drive = filename[0];
+	
+	 // hasDrive means it begins with a drive, e.g. "c:"
+	 const TBool hasDrive =  ((drive >= 'A' && drive <= 'Z') || (drive >= 'a' && drive <= 'z')) && (filename[1] == KDriveSeparator);
+	 // hasTopPath means it begins with a \ (possibly after the drive)
+	 const TBool hasTopPath = (hasDrive && (filename[2] == KFilePathSeparator)) || (!hasDrive && (drive == TUint(KFilePathSeparator) ));
+ 
+	 TInt skip = KDefaultPath().Length(); //  skip leading "<drive>:\" by default
+	 if(aFlags & TUint(EPrivate)) 
+		{
+		skip = (hasDrive ? (KDefaultPath().Length() - 1) : 0) + (hasTopPath ? 1 : 0) ;
+		}
+	 else
+		{
+		// if not private then it should have valid drive i.e. "<drive>:\"
+		if (!(hasDrive && hasTopPath)) 
+			{
+			User::Leave(KErrBadName);
+			}
+		}
+	
+	if(skip)
+		  {
+		  filename.Set(aFileName.Right(origLength - skip));
+		  } 	
+
+	TInt uriLen = aFileName.Length() + KExtMedia().Length() + KPrivate().Length() + 1 /* for drive letter */;
+	
+	HBufC* fileUri = HBufC::NewLC(uriLen);
+	TPtr fileUriPtr = fileUri->Des(); 
+	fileUriPtr.Append(KUriPathSeparator);
+	
+	if (aFlags & TUint(EPrivate))
+		{
+		fileUriPtr.Append(KPrivate);
+		drive = TInt16('A' + aDrive);
+		}
+		
+	if (aFlags & EExtMedia)
+		{
+		fileUriPtr.Append(KExtMedia);			
+		}
+	else
+		{
+		fileUriPtr.Append(drive);
+		fileUriPtr.Append(KUriPathSeparator);	
+		}
+		
+	fileUriPtr.Append(filename);
+		
+	//Convert "\" to "/"
+	ChangePathSeparator(fileUriPtr, KFilePathSeparator, KUriPathSeparator);
+
+	//Handling "./" and "../" in the file URI path  or resolving the URI path 
+	CDelimitedPath16* resolvedPath = CDelimitedPath16::NewLC(fileUriPtr);
+ 	// Clean up the path to resolve occurences of '..' and '.'
+ 	CleanResolvedPathL<TPtrC>(resolvedPath);
+ 	fileUriPtr.Copy(resolvedPath->Parser().Des()); // new path will always be shorter than old one
+ 	CleanupStack::PopAndDestroy(resolvedPath);
+ 		
+	CleanupStack::Pop(fileUri);
+	return fileUri;
+	}