Update contrib.
1 // Copyright (c) 2001-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include <uriutilscommon.h>
18 #include "UriUtilsInternal.h"
19 #include <escapeutils.h>
23 _LIT8(KDotSlash, "./");
24 _LIT8(KDotDotSlash, "../");
26 _LIT8(KSlashDot, "/.");
27 _LIT8(KSlashDotDot, "/..");
28 _LIT8(KSlashDotSlash, "/./");
29 _LIT8(KSlashDotDotSlash, "/../");
31 _LIT(KHexDigit, "0123456789ABCDEF");
32 _LIT(KUnreserved, "-.~_");
34 _LIT(KNormalisationUriPanicCategory, "URI-NORMALIZATION");
36 const TInt KEscapeIndicator = '%';
37 const TInt KEscapeTripleLength = 3;
38 const TInt KEscDelimiterPos = 0;
39 const TInt KMostSignificantNibblePos = 1;
40 const TInt KLeastSignificantNibblePos = 2;
41 const TInt KSubstringLength = 3;
42 const TInt KUpdateLength = 2;
43 const TInt KAttachLength = 1;
45 const TInt KDotLength = 1;
46 const TInt KDotDotLength = 2;
47 const TInt KDotDotSlashLength = 3;
48 const TInt KSlashDotDotSlashLength = 4;
52 // Implementation of UriUtils
57 Converts a 16-bit format uri into its internet form. Any Unicode characters
58 are converted into Utf8 representation and then any excluded characters are
59 escape encoded. Reserved characters specified in RFC2396 will not be escape
60 encoded however, these include ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ",".
61 For example http://localhost will not be encoded to http%3A%2F%2Flocalhost.
64 @deprecated Deprecated in 9.1
65 @leave KUriUtilsCannotConvert. When the input data cannot be converted.
66 @leave KUriUtilsErr16BitChar. When the input data has a 16-Bit character to be escape encoded.
67 @param aUri The 16-bit format uri.
68 @return A pointer to a newly created 8-bit uri.
70 EXPORT_C CUri8* UriUtils::ConvertToInternetFormL(const TUriC16& aUri)
72 // Need to convert to utf8
73 HBufC8* utf8Buf = EscapeUtils::ConvertFromUnicodeToUtf8L(aUri.UriDes());
74 CleanupStack::PushL(utf8Buf);
76 // Ok need to parse for the uri without the fragment
78 parser.Parse(*utf8Buf);
80 parser.UriWithoutFragment(uriNoFragment);
82 // Now escape encode the uri without the fragment
83 HBufC8* escapedBuf = EscapeUtils::EscapeEncodeL(uriNoFragment, EscapeUtils::EEscapeNormal);
84 CleanupStack::PushL(escapedBuf);
86 // Now escape encode the fragment if there is one...
87 HBufC8* escapedFragmentBuf = NULL;
88 if( parser.IsPresent(EUriFragment) )
90 escapedFragmentBuf = EscapeUtils::EscapeEncodeL(parser.Extract(EUriFragment), EscapeUtils::EEscapeNormal);
91 CleanupStack::PushL(escapedFragmentBuf);
94 // Parse and then create the CUri8 object
95 parser.Parse(*escapedBuf);
96 CUri8* netForm = CUri8::NewL(parser);
98 // Set the fragment if there was one...
99 if( escapedFragmentBuf != NULL )
101 CleanupStack::PushL(netForm);
102 netForm->SetComponentL(*escapedFragmentBuf, EUriFragment);
103 CleanupStack::Pop(netForm);
104 CleanupStack::PopAndDestroy(escapedFragmentBuf);
107 // Cleanup and return
108 CleanupStack::PopAndDestroy(2, utf8Buf); // utf8Buf, escapedBuf
113 Converts an 8-bit format uri its into display form. Any escape tripes are decoded and
114 sets of Utf8 format characters are converted into Unicode.
117 @deprecated Deprecated in 9.1
118 @leave KUriUtilsCannotConvert. When the input data cannot be converted.
119 @param aUri The 8-bit format uri.
120 @return A pointer to a newly created 16-bit uri.
122 EXPORT_C CUri16* UriUtils::ConvertToDisplayFormL(const TUriC8& aUri)
124 // Need decode escape triples
125 HBufC8* unescapedBuf = EscapeUtils::EscapeDecodeL(aUri.UriDes());
126 CleanupStack::PushL(unescapedBuf);
128 // Now need to convert utf8 to unicode
129 HBufC16* utf8Buf = EscapeUtils::ConvertToUnicodeFromUtf8L(*unescapedBuf);
130 CleanupStack::PushL(utf8Buf);
132 // Parse and then create the CUri16 object
134 parser.Parse(*utf8Buf);
135 CUri16* displayForm = CUri16::NewL(parser);
137 // Cleanup and return
138 CleanupStack::PopAndDestroy(2, unescapedBuf); // unescapedBuf, utf8Buf
143 Create a new CUri8 object from a Unicode descriptor.
145 @param aUri a Unicode string containing the URI to parse.
146 @return the new CUri8 object
147 @leave EUriUtilsParserErrInvalidUri if the descriptor is an invalid URI.
149 EXPORT_C CUri8* UriUtils::CreateUriL(const TDesC& aUri)
152 HBufC8* unsafe8 = EscapeUtils::ConvertFromUnicodeToUtf8L(aUri);
153 CleanupStack::PushL(unsafe8);
154 // escape encode only those characters that cannot be in a URI. assume all %hh are %encoded already
155 HBufC8* uri8desc = EscapeUtils::ReEscapeEncodeL(*unsafe8);
156 CleanupStack::PopAndDestroy(unsafe8);
157 CleanupStack::PushL(uri8desc);
159 // parse the descriptor into a URI, Leave if it cannot be parsed
160 User::LeaveIfError( parser.Parse(*uri8desc) );
162 CUri8* uri8 = CUri8::NewL(parser);
163 CleanupStack::PopAndDestroy(uri8desc);
168 Create a new CAuthority8 object from a Unicode descriptor.
170 @param aAuthority a Unicode string containing the Authority to parse.
171 @return the new CAuthority8 object
172 @leave EUriUtilsParserErrInvalidUri if the descriptor is an invalid Authority.
174 EXPORT_C CAuthority8* UriUtils::CreateAuthorityL(const TDesC& aAuthority)
177 HBufC8* unsafe8 = EscapeUtils::ConvertFromUnicodeToUtf8L(aAuthority);
178 CleanupStack::PushL(unsafe8);
179 // escape encode only those characters that cannot be in the authority. assume all %s are %encoded already
180 HBufC8* authority8desc = EscapeUtils::ReEscapeEncodeL(*unsafe8);
181 CleanupStack::PopAndDestroy(unsafe8);
182 CleanupStack::PushL(authority8desc);
183 TAuthorityParser8 parser;
184 // parse the descriptor into the authority, Leave if it cannot be parsed
185 User::LeaveIfError( parser.Parse(*authority8desc) );
187 CAuthority8* authority8 = CAuthority8::NewL(parser);
188 CleanupStack::PopAndDestroy(authority8desc);
193 Checks a descriptor for excluded (invalid) characters. Excluded characters include all
194 control characters (values 0x00 to 0x1F and greater than 0x7F), space (0x20), delimiter
195 characters ('<', '>', '#', '%', '"') and unwise characters ('{', '}', '|', '\', '^', '[', ']', '`').
198 @param aData The descriptor to be checked.
199 @return A boolean value of ETrue if the descriptor contains invalid
200 characters, otherwise EFalse.
202 EXPORT_C TBool UriUtils::HasInvalidChars(const TDesC8& aData)
204 return CheckForExcludedChars(aData);
208 Checks a descriptor for excluded (invalid) characters. Excluded characters include all
209 control characters (values 0x00 to 0x1F and greater than 0x7F), space (0x20), delimiter
210 characters ('<', '>', '#', '%','"') and unwise characters ('{', '}', '|', '\', '^', '[', ']', '`').
213 @param aData The descriptor to be checked.
214 @return A boolean value of ETrue if the descriptor contains invalid
215 characters, otherwise EFalse.
217 EXPORT_C TBool UriUtils::HasInvalidChars(const TDesC16& aData)
219 return CheckForExcludedChars(aData);
223 Checks the supplied host for an IPv4, IPv6 or text format host
226 @param aHost The descriptor containing the host to check
227 @return A TUriHostType enum of either EIPv6, EIPv4, EText or EUnknown
229 EXPORT_C UriUtils::TUriHostType UriUtils::HostType(const TDesC8& aHost)
231 return CheckHostType(aHost);
235 Checks the supplied host for an IPv4, IPv6 or text format host
238 @param aHost The descriptor containing the host to check
239 @return A TUriHostType enum of either EIPv6, EIPv4, EText or EUnknown
241 EXPORT_C UriUtils::TUriHostType UriUtils::HostType(const TDesC16& aHost)
243 return CheckHostType(aHost);
250 // Implementation of component internal functions
257 Checks whether the given scheme is a network scheme or not
259 @param aScheme The descriptor with the scheme.
260 @return A boolean value of EFalse if the scheme is SIP. For all other schemes returns ETrue.
262 TBool IsNetworkScheme(const TDesC8& aScheme)
264 TUriSchemeType scheme = SchemeType(aScheme);
265 if (scheme == ESchemeTypeSip)
275 Checks whether the given scheme is a network scheme or not
277 @param aScheme The descriptor with the scheme.
278 @return A boolean value of EFalse if the scheme is SIP. For all other schemes returns ETrue.
280 TBool IsNetworkScheme(const TDesC16& aScheme)
282 TUriSchemeType scheme = SchemeType(aScheme);
283 if (scheme == ESchemeTypeSip)
293 Returns the type of the URIs scheme
295 @param aScheme The descriptor with the scheme.
296 @return The scheme type
298 TUriSchemeType SchemeType(const TDesC8& aScheme)
300 // Compares the scheme with both sip and sips
301 if (aScheme.CompareF(KSipScheme8()) == 0 || aScheme.CompareF(KSipsScheme8()) == 0)
303 // there's a match so this is a sip scheme
304 return ESchemeTypeSip;
306 //Compares the scheme with tel
307 else if (aScheme.CompareF(KTelScheme8()) == 0)
309 return ESchemeTypeTel;
312 return ESchemeTypeUnknown;
318 Returns the type of the URIs scheme
320 @param aScheme The descriptor with the scheme.
321 @return The scheme type
323 TUriSchemeType SchemeType(const TDesC16& aScheme)
325 // Compares the scheme with both sip and sips
326 if (aScheme.CompareF(KSipScheme()) == 0 || aScheme.CompareF(KSipsScheme()) == 0)
328 // there's a match so this is a sip scheme
329 return ESchemeTypeSip;
332 return ESchemeTypeUnknown;
338 Checks that a text host is in a valid form
340 @param aHost The descriptor containing the host to check
341 @return ETrue if the host is valid otherwise EFalse
343 TBool IsTextHostValid(const TDesC8& aHost)
345 return CheckValidTextHost(aHost);
351 Checks that a text host is in a valid form
353 @param aHost The descriptor containing the host to check
354 @return ETrue if the host is valid otherwise EFalse
356 TBool IsTextHostValid(const TDesC16& aHost)
358 return CheckValidTextHost(aHost);
365 Parses a segment of the form name=value and returns the name and value parts
367 @param aSegment the name-value segemnt to parse
368 @param aName the name part that is returned
369 @param aValue the value part that is returned
371 void GetNameValuePair(const TDesC8& aSegment, TPtrC8& aName, TPtrC8& aValue)
374 TInt sepPos = aSegment.Locate(KEqualsSeparator);
375 if (sepPos != KErrNotFound)
377 aName.Set(aSegment.Left(sepPos));
378 value.Set(aSegment.Mid(sepPos+1));
391 // Implementation of LOCAL functions
396 Checks the descriptor for any excluded characters. These are characters that
397 should have been escaped encoded or ocnverted to Utf8 from Unicode.
400 @param aData The descriptor to be checked.
401 @return A boolean value of ETrue if the descriptor contains excluded
402 characters, EFalse if it does not.
404 template<class TDesCType>
405 LOCAL_C TBool CheckForExcludedChars(const TDesCType& aData)
407 // Run through the descriptor
409 const TInt length = aData.Length();
411 while( valid && i<length )
414 // See if the character is an excluded one, or is part of an escape triple...
415 if( EscapeUtils::IsExcludedChar(aData[i]) && !EscapeUtils::IsEscapeTriple(aData.Mid(i), notUsed) )
428 Checks the supplied host for an IPv4, IPv6 or text format host
431 @param aHost The descriptor containing the host to check
432 @return A TUriHostType enum of either EIPv6, EIPv4, EText or EUnknown
434 template<class TDesCType>
435 LOCAL_C UriUtils::TUriHostType CheckHostType(const TDesCType& aHost)
437 UriUtils::TUriHostType hostType;
440 TBool colonPresent=EFalse;
443 TInt len = aHost.Length();
444 for (TInt ii=0; ii < len && !colonPresent; ++ii)
448 // host contains a character that is not '0'..'9' or '.'
449 if ((ch < 48 || ch > 57) && ch != 46)
452 // need to check that IPv4 address has the 3 dots
460 if (colonPresent) // if theres a colon, it has to be an IPv6 address
461 hostType = UriUtils::EIPv6Host;
463 if (numeric && (dotCount==3)) // if its numeric only, and has three seperators...
464 hostType = UriUtils::EIPv4Host;
466 hostType = UriUtils::ETextHost;
474 Checks that a text host is in a valid form
476 @param aHost The descriptor containing the host to check
477 @return ETrue if the host is valid otherwise EFalse
479 template<class TDesCType>
480 LOCAL_C TBool CheckValidTextHost(const TDesCType& aHost)
482 TInt len = aHost.Length();
486 // host name can't start with a dot or dash
487 TChar firstChar(aHost[0]);
488 if (firstChar == '-' || firstChar == '.')
493 for (ii=0; ii < len; ii++)
497 // Valid characters are a-z, 0-9, '-' and '.'
498 if ((ch < 'A' || ch > 'Z') && (ch < 'a' || ch > 'z') && (ch < '0' || ch > '9') && ch != '-' && ch != '.')
503 // dot is the section separator. Check the previous section is not empty
504 if (ch == '.' && prev == '.')
506 // can't have an empty section
512 // host name can't end with a dot or dash
513 if (prev == '-' || prev == '.')
520 Supports Syntax-Based Normalization as specifed in section 6.2.2 of RFC3986.
521 returns a new CUri8 object containing a normalised URI from a parsed URI object.
523 @param aUri A reference to a parsed uri object.
524 @return A pointer to a CUri8 object containing normalised URI.
528 EXPORT_C CUri8* UriUtils:: NormaliseUriL(const TUriC8& aUri)
530 CUri8* normalisedUri = CUri8::NewLC(aUri);
531 PercentEncodeL(normalisedUri);
532 CaseNormaliseL(normalisedUri);
533 RemoveDotSegmentsL(normalisedUri);
534 CleanupStack::Pop(normalisedUri);
535 return normalisedUri;
539 Performs Case Normalization for CUri8 object as specified
540 in section 6.2.2.1 of RFC3986.
542 @param aNormalisedUri It is an in-out parameter. aNormalisedUri is a pointer
543 to CUri8 object with an uri needs to be case normalised and returns with
547 void CaseNormaliseL(CUri8* aNormalisedUri )
549 //Case normalise the scheme
550 DoCaseNormaliseL(aNormalisedUri, EUriScheme);
551 //Case normalise the Userinfo
552 DoCaseNormaliseL(aNormalisedUri, EUriUserinfo);
553 //Case normalise the Host
554 DoCaseNormaliseL(aNormalisedUri, EUriHost);
555 //Case normalise the Port
556 DoCaseNormaliseL(aNormalisedUri, EUriPort);
557 //Case normalise the Path
558 DoCaseNormaliseL(aNormalisedUri, EUriPath);
559 //Case normalise the Query
560 DoCaseNormaliseL(aNormalisedUri, EUriQuery);
561 //Case normalise the Fragment
562 DoCaseNormaliseL(aNormalisedUri, EUriFragment);
566 Performs Case Normalization for specified sub component of URI.
568 @param aNormalisedUri It is an in-out parameter. aNormalisedUri is a pointer
569 to CUri8 object with an uri needs to be case normalised and returns with
570 case normalised for specified sub component.
571 @param aComponent Enumeration of TUriComponent.
574 void DoCaseNormaliseL(CUri8* aNormalisedUri, TUriComponent aComponent)
576 const TUriC8& uri(aNormalisedUri->Uri());
577 if(!uri.IsPresent(aComponent) )
581 //extracts subcomponent of uri which needs to be case-normalised
582 HBufC8* heapBuf = uri.Extract(aComponent).AllocLC();
583 TPtr8 normalisedComponent(heapBuf->Des());
584 TBool normalised = EFalse;
585 if(aComponent == EUriScheme || aComponent == EUriHost )
587 //change this component to lower case
588 normalisedComponent.LowerCase();
592 TInt len = normalisedComponent.Length();
593 TBuf8<KSubstringLength> subString;
594 //case normalise the component
595 for (TInt pos = 0; pos < len; pos++)
597 if (normalisedComponent[pos] == KEscapeIndicator )
599 __ASSERT_DEBUG( ((len-pos) >= KSubstringLength), User::Panic(KNormalisationUriPanicCategory, KUriUtilsErrBadEscapeTriple) );
600 TPtrC8 componentBuf(normalisedComponent.Mid(pos,KSubstringLength));
601 if (ValidateAndConvertPercentEncodedTriple(componentBuf,subString))
603 normalisedComponent.Replace(pos,KSubstringLength,subString);
604 pos += KUpdateLength;
611 //updating the uri with normalised string
614 if(aComponent<EUriMaxComponents && aComponent >=EUriScheme)
616 aNormalisedUri->SetComponentL(normalisedComponent, aComponent);
620 User::Leave(KErrArgument);
624 CleanupStack::PopAndDestroy(heapBuf);
628 Validates and Converts the valid Percent encoded triplets to Uppercase for specified
629 sub component of URI. For eg: Converts %3a to %3A
631 @param aData A reference to a string to be validated and converted to upper case.
632 @param aCaseNormalizedData A reference to a descriptor that is converted to
633 uppercase that is to be returned.
634 @return returns a bool whether it is a valid Percent encoded triplet
636 TBool ValidateAndConvertPercentEncodedTriple(TDesC8& aData , TDes8& aCaseNormalizedData )
638 // See if the descriptor is actually long enough and
639 // Check that the three characters form an escape triple - first char is '%'
640 if( aData.Length() < KEscapeTripleLength || aData[KEscDelimiterPos] != KEscapeIndicator )
642 return EFalse;//do nothing
645 // Check that next two characters are valid
646 TInt mostSignificantDigitValue = KHexDigit().LocateF(aData[KMostSignificantNibblePos] );
647 TInt leastSignificantDigitValue = KHexDigit().LocateF(aData[KLeastSignificantNibblePos] );
649 if( mostSignificantDigitValue== KErrNotFound || leastSignificantDigitValue == KErrNotFound )
651 // Either of the characters were not a valid hex character
654 aCaseNormalizedData.Zero();
655 aCaseNormalizedData.Append(KEscapeIndicator);
657 //Coverts most significant hex character to uppercase
658 (mostSignificantDigitValue >= 0 && mostSignificantDigitValue <= 0xF) ?
659 aCaseNormalizedData.Append(KHexDigit().Mid(mostSignificantDigitValue,1)) :
660 aCaseNormalizedData.Append(KHexDigit().Mid(mostSignificantDigitValue,1));
662 //Coverts least significant hex character to uppercase
663 (leastSignificantDigitValue >= 0 && leastSignificantDigitValue <= 0xF) ?
664 aCaseNormalizedData.Append(KHexDigit().Mid(leastSignificantDigitValue,1)) :
665 aCaseNormalizedData.Append(aData[KLeastSignificantNibblePos]);
671 Performs Percent-Encoding Normalization for CUri8 object as specifed in
672 section 6.2.2.2 of RFC3986.
674 @param aNormalisedUri It is an in-out parameter. aNormalisedUri is a pointer to
675 CUri8 object with an uri needs to be Percent-Encoded and returns with Percent-Encode
679 void PercentEncodeL(CUri8* aNormalisedUri)
681 //PercentEncode the scheme
682 DoPercentEncodeL(aNormalisedUri, EUriScheme);
683 //PercentEncode the Userinfo
684 DoPercentEncodeL(aNormalisedUri, EUriUserinfo);
685 //PercentEncode the Host
686 DoPercentEncodeL(aNormalisedUri, EUriHost);
687 //PercentEncode the Port
688 DoPercentEncodeL(aNormalisedUri, EUriPort);
689 //PercentEncode the Path
690 DoPercentEncodeL(aNormalisedUri, EUriPath);
691 //PercentEncode the Query
692 DoPercentEncodeL(aNormalisedUri, EUriQuery);
693 //PercentEncode the Fragment
694 DoPercentEncodeL(aNormalisedUri, EUriFragment);
698 Performs Percent-Encoding for specified sub component of URI.
700 @param aNormalisedUri It is an in-out parameter. aNormalisedUri is a pointer to
701 CUri8 object with an uri needs to be Percent-Encoded and returns with Percent-Encoded
702 for specified sub component.
703 @param aComponent Enumeration of TUriComponent.
706 void DoPercentEncodeL(CUri8* aNormalisedUri, TUriComponent aComponent)
708 const TUriC8& uri(aNormalisedUri->Uri());
709 if(!uri.IsPresent(aComponent))
714 HBufC8* heapBuf = uri.Extract(aComponent).AllocLC();
715 TPtr8 percentNormalisedComponent(heapBuf->Des());
716 TBool normalised = EFalse;
717 TInt len = percentNormalisedComponent.Length();
718 for (TInt pos = 0; pos < len; pos++)
721 // check for and decode '%' encoded characters
722 if (percentNormalisedComponent[pos] == KEscapeIndicator && EscapeUtils::IsEscapeTriple(percentNormalisedComponent.Mid(pos, KSubstringLength), hex))
724 TChar replacedChar(hex);
725 if( KUnreserved().LocateF(hex) != KErrNotFound || replacedChar.IsAlphaDigit() )
727 TBuf8<KAttachLength> subString;
728 subString.Append(replacedChar);
729 percentNormalisedComponent.Replace(pos, KSubstringLength, subString);
731 len = percentNormalisedComponent.Length();
737 if(aComponent<EUriMaxComponents && aComponent >=EUriScheme)
739 aNormalisedUri->SetComponentL(percentNormalisedComponent, aComponent);
743 User::Leave(KErrArgument);
747 CleanupStack::PopAndDestroy(heapBuf);
751 Performs Path Segment Normalization for CUri8 object as specifed in
752 section 6.2.2.3 of RFC3986.
754 @param aNormalisedUri It is an in-out parameter. aNormalisedUri is a pointer to
755 CUri8 object with uri needs to be Path Segment normalised and returns with
756 Path Segment normalised form.
759 void RemoveDotSegmentsL(CUri8* aNormalisedUri)
761 const TUriC8& uri( aNormalisedUri->Uri() );
762 if(uri.IsPresent(EUriPath))
764 HBufC8* dotSegmentsPath = uri.Extract(EUriPath).AllocLC();
765 RemoveExtraneousDotSegmentsL(dotSegmentsPath);
766 aNormalisedUri->SetComponentL(*dotSegmentsPath, EUriPath);
767 CleanupStack::PopAndDestroy(dotSegmentsPath);
772 Performs Remove_dot_segments algorithm as specifed in section 5.2.4 of RFC3986.
774 @param aUriInputPath It is an in-out parameter. aUriInputPath is a pointer to the
775 path descriptor to be normalised for extraneous dot_segments and returns with
776 normalised dot_segments.
779 void RemoveExtraneousDotSegmentsL(HBufC8* aUriInputPath)
781 TPtr8 uriPathBuf(aUriInputPath->Des());
782 TInt length = uriPathBuf.Length();
783 HBufC8* path = HBufC8::NewLC(length);
784 TPtr8 transitionalBuf(path->Des());
788 //step a of section 5.2.4 of RFC 3986
789 if(length >= KDotDotSlashLength &&
790 KDotDotSlash().Compare(uriPathBuf.Mid(0, KDotDotSlashLength)) == 0 )
792 uriPathBuf.Delete(0,KDotDotSlashLength);
794 //step a of section 5.2.4 of RFC 3986
795 else if(length >= KDotDotLength &&
796 KDotSlash().Compare(uriPathBuf.Mid(0, KDotDotLength)) == 0)
798 uriPathBuf.Delete(0,KDotDotLength);
800 //step b of section 5.2.4 of RFC 3986
801 else if(length >= KDotDotSlashLength &&
802 KSlashDotSlash().Compare(uriPathBuf.Mid(0, KDotDotSlashLength)) == 0)
804 uriPathBuf.Replace(0, KDotDotSlashLength, KSlash);
806 //step c of section 5.2.4 of RFC 3986
807 else if(length >= KSlashDotDotSlashLength &&
808 KSlashDotDotSlash().Compare(uriPathBuf.Mid(0, KSlashDotDotSlashLength)) == 0)
810 updateStrings(uriPathBuf, transitionalBuf, KSlashDotDotSlashLength);
812 //step c of section 5.2.4 of RFC 3986 --complete path segment
813 else if(length == KDotDotSlashLength &&
814 KSlashDotDot().Compare(uriPathBuf.Mid(0, KDotDotSlashLength)) == 0)
816 updateStrings(uriPathBuf, transitionalBuf, KDotDotSlashLength);
818 //step b of section 5.2.4 of RFC 3986--complete path segment
819 else if(length == KDotDotLength &&
820 KSlashDot().Compare(uriPathBuf.Mid(0, KDotDotLength)) == 0)
822 uriPathBuf.Replace(0, KDotDotLength, KSlash);
824 //step d of section 5.2.4 of RFC 3986
825 else if(length == KDotDotLength &&
826 KDotDot().Compare(uriPathBuf.Mid(0)) == 0)
828 uriPathBuf.Delete(0,KDotDotLength);
830 //step d of section 5.2.4 of RFC 3986
831 else if(length == KDotLength &&
832 KDot().Compare(uriPathBuf.Mid(0)) == 0)
834 uriPathBuf.Delete(0,KDotLength);
836 //step e of section 5.2.4 of RFC 3986
839 //get the first path segment including initial / (if any)from uriPathBuf
840 // till next slash (but not including next slash)..append it to the output Buf
842 TInt nextSlashPos = uriPathBuf.Find(KSlash);
843 if(nextSlashPos == 0 && length > KDotLength)
844 //replace with locate next
846 nextSlashPos = uriPathBuf.Mid(1).Find(KSlash);
847 if(nextSlashPos != KErrNotFound)
852 if(length == KDotLength)
855 substrLength = length;
859 substrLength = nextSlashPos == KErrNotFound ? length : nextSlashPos ;
861 transitionalBuf.Append(uriPathBuf.Mid(0,substrLength));
862 uriPathBuf.Delete(0,substrLength);
864 length = uriPathBuf.Length();
866 uriPathBuf.Copy(transitionalBuf);
867 CleanupStack::PopAndDestroy(path);
871 Updates the strings specified in step c of section 5.2.4 of RFC 3986
873 @param aInputBuf A reference to the inputBuf needs to be modified
874 @param aOutPutBuf A reference to the outPutBuf needs to be modified
875 @param aLength length of the string to be replaced.
877 void updateStrings(TPtr8& aInputBuf, TPtr8& aOutPutBuf, TInt aLength)
879 aInputBuf.Replace(0,aLength,KSlash);
881 //In outPutBuf to remove the last segment starting with / (if exist)
882 //eg: /abc/def/fgh --> /abc/def
883 TInt outputBufLength = aOutPutBuf.Length();
884 TInt pos = aOutPutBuf.LocateReverse('/');
885 //remove the last segment including '/'
886 pos != KErrNotFound ? aOutPutBuf.Delete( pos, outputBufLength - pos ) : aOutPutBuf.Delete( 0,outputBufLength );