urlmon: Implemented IUri_IsEqual.
This commit is contained in:
parent
d0d7663c10
commit
364b804d9e
@ -3623,28 +3623,79 @@ static const uri_equality equality_tests[] = {
|
|||||||
{
|
{
|
||||||
"HTTP://www.winehq.org/test dir/./",0,FALSE,
|
"HTTP://www.winehq.org/test dir/./",0,FALSE,
|
||||||
"http://www.winehq.org/test dir/../test dir/",0,FALSE,
|
"http://www.winehq.org/test dir/../test dir/",0,FALSE,
|
||||||
TRUE, TRUE
|
TRUE, FALSE
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
/* http://www.winehq.org/test%20dir */
|
/* http://www.winehq.org/test%20dir */
|
||||||
"http://%77%77%77%2E%77%69%6E%65%68%71%2E%6F%72%67/%74%65%73%74%20%64%69%72",0,FALSE,
|
"http://%77%77%77%2E%77%69%6E%65%68%71%2E%6F%72%67/%74%65%73%74%20%64%69%72",0,FALSE,
|
||||||
"http://www.winehq.org/test dir",0,FALSE,
|
"http://www.winehq.org/test dir",0,FALSE,
|
||||||
TRUE, TRUE,
|
TRUE, FALSE
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"c:\\test.mp3",Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME,FALSE,
|
"c:\\test.mp3",Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME,FALSE,
|
||||||
"file:///c:/test.mp3",0,FALSE,
|
"file:///c:/test.mp3",0,FALSE,
|
||||||
TRUE,TRUE
|
TRUE, FALSE
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ftp://ftp.winehq.org/",0,FALSE,
|
"ftp://ftp.winehq.org/",0,FALSE,
|
||||||
"ftp://ftp.winehq.org",0,FALSE,
|
"ftp://ftp.winehq.org",0,FALSE,
|
||||||
TRUE, TRUE
|
TRUE, FALSE
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"ftp://ftp.winehq.org/test/test2/../../testB/",0,FALSE,
|
"ftp://ftp.winehq.org/test/test2/../../testB/",0,FALSE,
|
||||||
"ftp://ftp.winehq.org/t%45stB/",0,FALSE,
|
"ftp://ftp.winehq.org/t%45stB/",0,FALSE,
|
||||||
FALSE, TRUE
|
FALSE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"http://google.com/TEST",0,FALSE,
|
||||||
|
"http://google.com/test",0,FALSE,
|
||||||
|
FALSE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"http://GOOGLE.com/",0,FALSE,
|
||||||
|
"http://google.com/",0,FALSE,
|
||||||
|
TRUE, FALSE
|
||||||
|
},
|
||||||
|
/* Performs case insensitive compare of host names (for known scheme types). */
|
||||||
|
{
|
||||||
|
"ftp://GOOGLE.com/",Uri_CREATE_NO_CANONICALIZE,FALSE,
|
||||||
|
"ftp://google.com/",0,FALSE,
|
||||||
|
TRUE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"zip://GOOGLE.com/",0,FALSE,
|
||||||
|
"zip://google.com/",0,FALSE,
|
||||||
|
FALSE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file:///c:/TEST/TeST/",0,FALSE,
|
||||||
|
"file:///c:/test/test/",0,FALSE,
|
||||||
|
TRUE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file:///server/TEST",0,FALSE,
|
||||||
|
"file:///SERVER/TEST",0,FALSE,
|
||||||
|
TRUE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"http://google.com",Uri_CREATE_NO_CANONICALIZE,FALSE,
|
||||||
|
"http://google.com/",0,FALSE,
|
||||||
|
TRUE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ftp://google.com:21/",0,FALSE,
|
||||||
|
"ftp://google.com/",0,FALSE,
|
||||||
|
TRUE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"http://google.com:80/",Uri_CREATE_NO_CANONICALIZE,FALSE,
|
||||||
|
"http://google.com/",0,FALSE,
|
||||||
|
TRUE, FALSE
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"http://google.com:70/",0,FALSE,
|
||||||
|
"http://google.com:71/",0,FALSE,
|
||||||
|
FALSE, FALSE
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||||
|
|
||||||
|
static const IID IID_IUriObj = {0x4b364760,0x9f51,0x11df,{0x98,0x1c,0x08,0x00,0x20,0x0c,0x9a,0x66}};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const IUriVtbl *lpIUriVtbl;
|
const IUriVtbl *lpIUriVtbl;
|
||||||
LONG ref;
|
LONG ref;
|
||||||
@ -194,6 +196,15 @@ static const struct {
|
|||||||
{{'o','r','g',0}}
|
{{'o','r','g',0}}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Uri *get_uri_obj(IUri *uri)
|
||||||
|
{
|
||||||
|
Uri *ret;
|
||||||
|
HRESULT hres;
|
||||||
|
|
||||||
|
hres = IUri_QueryInterface(uri, &IID_IUriObj, (void**)&ret);
|
||||||
|
return SUCCEEDED(hres) ? ret : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline BOOL is_alpha(WCHAR val) {
|
static inline BOOL is_alpha(WCHAR val) {
|
||||||
return ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'));
|
return ((val >= 'a' && val <= 'z') || (val >= 'A' && val <= 'Z'));
|
||||||
}
|
}
|
||||||
@ -280,6 +291,104 @@ static inline BOOL is_path_delim(WCHAR val) {
|
|||||||
return (!val || val == '#' || val == '?');
|
return (!val || val == '#' || val == '?');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Checks if the two Uri's are logically equivalent. It's a simple
|
||||||
|
* comparison, since they are both of type Uri, and it can access
|
||||||
|
* the properties of each Uri directly without the need to go
|
||||||
|
* through the "IUri_Get*" interface calls.
|
||||||
|
*/
|
||||||
|
static BOOL are_equal_simple(const Uri *a, const Uri *b) {
|
||||||
|
if(a->scheme_type == b->scheme_type) {
|
||||||
|
const BOOL known_scheme = a->scheme_type != URL_SCHEME_UNKNOWN;
|
||||||
|
const BOOL are_hierarchical =
|
||||||
|
(a->authority_start > -1 && b->authority_start > -1);
|
||||||
|
|
||||||
|
if(a->scheme_type == URL_SCHEME_FILE) {
|
||||||
|
if(a->canon_len == b->canon_len)
|
||||||
|
return !StrCmpIW(a->canon_uri, b->canon_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only compare the scheme names (if any) if their unknown scheme types. */
|
||||||
|
if(!known_scheme) {
|
||||||
|
if((a->scheme_start > -1 && b->scheme_start > -1) &&
|
||||||
|
(a->scheme_len == b->scheme_len)) {
|
||||||
|
/* Make sure the schemes are the same. */
|
||||||
|
if(StrCmpNW(a->canon_uri+a->scheme_start, b->canon_uri+b->scheme_start, a->scheme_len))
|
||||||
|
return FALSE;
|
||||||
|
} else if(a->scheme_len != b->scheme_len)
|
||||||
|
/* One of the Uri's has a scheme name, while the other doesn't. */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If they have a userinfo component, perform case sensitive compare. */
|
||||||
|
if((a->userinfo_start > -1 && b->userinfo_start > -1) &&
|
||||||
|
(a->userinfo_len == b->userinfo_len)) {
|
||||||
|
if(StrCmpNW(a->canon_uri+a->userinfo_start, b->canon_uri+b->userinfo_start, a->userinfo_len))
|
||||||
|
return FALSE;
|
||||||
|
} else if(a->userinfo_len != b->userinfo_len)
|
||||||
|
/* One of the Uri's had a userinfo, while the other one doesn't. */
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Check if they have a host name. */
|
||||||
|
if((a->host_start > -1 && b->host_start > -1) &&
|
||||||
|
(a->host_len == b->host_len)) {
|
||||||
|
/* Perform a case insensitive compare if they are a known scheme type. */
|
||||||
|
if(known_scheme) {
|
||||||
|
if(StrCmpNIW(a->canon_uri+a->host_start, b->canon_uri+b->host_start, a->host_len))
|
||||||
|
return FALSE;
|
||||||
|
} else if(StrCmpNW(a->canon_uri+a->host_start, b->canon_uri+b->host_start, a->host_len))
|
||||||
|
return FALSE;
|
||||||
|
} else if(a->host_len != b->host_len)
|
||||||
|
/* One of the Uri's had a host, while the other one didn't. */
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if(a->has_port && b->has_port) {
|
||||||
|
if(a->port != b->port)
|
||||||
|
return FALSE;
|
||||||
|
} else if(a->has_port || b->has_port)
|
||||||
|
/* One had a port, while the other one didn't. */
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Windows is weird with how it handles paths. For example
|
||||||
|
* One URI could be "http://google.com" (after canonicalization)
|
||||||
|
* and one could be "http://google.com/" and the IsEqual function
|
||||||
|
* would still evaluate to TRUE, but, only if they are both hierarchical
|
||||||
|
* URIs.
|
||||||
|
*/
|
||||||
|
if((a->path_start > -1 && b->path_start > -1) &&
|
||||||
|
(a->path_len == b->path_len)) {
|
||||||
|
if(StrCmpNW(a->canon_uri+a->path_start, b->canon_uri+b->path_start, a->path_len))
|
||||||
|
return FALSE;
|
||||||
|
} else if(are_hierarchical && a->path_len == -1 && b->path_len == 0) {
|
||||||
|
if(*(a->canon_uri+a->path_start) != '/')
|
||||||
|
return FALSE;
|
||||||
|
} else if(are_hierarchical && b->path_len == 1 && a->path_len == 0) {
|
||||||
|
if(*(b->canon_uri+b->path_start) != '/')
|
||||||
|
return FALSE;
|
||||||
|
} else if(a->path_len != b->path_len)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Compare the query strings of the two URIs. */
|
||||||
|
if((a->query_start > -1 && b->query_start > -1) &&
|
||||||
|
(a->query_len == b->query_len)) {
|
||||||
|
if(StrCmpNW(a->canon_uri+a->query_start, b->canon_uri+b->query_start, a->query_len))
|
||||||
|
return FALSE;
|
||||||
|
} else if(a->query_len != b->query_len)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if((a->fragment_start > -1 && b->fragment_start > -1) &&
|
||||||
|
(a->fragment_len == b->fragment_len)) {
|
||||||
|
if(StrCmpNW(a->canon_uri+a->fragment_start, b->canon_uri+b->fragment_start, a->fragment_len))
|
||||||
|
return FALSE;
|
||||||
|
} else if(a->fragment_len != b->fragment_len)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* If we get here, the two URIs are equivalent. */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Computes the size of the given IPv6 address.
|
/* Computes the size of the given IPv6 address.
|
||||||
* Each h16 component is 16bits, if there is an IPv4 address, it's
|
* Each h16 component is 16bits, if there is an IPv4 address, it's
|
||||||
* 32bits. If there's an elision it can be 16bits to 128bits, depending
|
* 32bits. If there's an elision it can be 16bits to 128bits, depending
|
||||||
@ -3008,6 +3117,10 @@ static HRESULT WINAPI Uri_QueryInterface(IUri *iface, REFIID riid, void **ppv)
|
|||||||
}else if(IsEqualGUID(&IID_IUri, riid)) {
|
}else if(IsEqualGUID(&IID_IUri, riid)) {
|
||||||
TRACE("(%p)->(IID_IUri %p)\n", This, ppv);
|
TRACE("(%p)->(IID_IUri %p)\n", This, ppv);
|
||||||
*ppv = URI(This);
|
*ppv = URI(This);
|
||||||
|
}else if(IsEqualGUID(&IID_IUriObj, riid)) {
|
||||||
|
TRACE("(%p)->(IID_IUriObj %p)\n", This, ppv);
|
||||||
|
*ppv = This;
|
||||||
|
return S_OK;
|
||||||
}else {
|
}else {
|
||||||
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
||||||
*ppv = NULL;
|
*ppv = NULL;
|
||||||
@ -3693,6 +3806,8 @@ static HRESULT WINAPI Uri_GetProperties(IUri *iface, DWORD *pdwProperties)
|
|||||||
static HRESULT WINAPI Uri_IsEqual(IUri *iface, IUri *pUri, BOOL *pfEqual)
|
static HRESULT WINAPI Uri_IsEqual(IUri *iface, IUri *pUri, BOOL *pfEqual)
|
||||||
{
|
{
|
||||||
Uri *This = URI_THIS(iface);
|
Uri *This = URI_THIS(iface);
|
||||||
|
Uri *other;
|
||||||
|
|
||||||
TRACE("(%p)->(%p %p)\n", This, pUri, pfEqual);
|
TRACE("(%p)->(%p %p)\n", This, pUri, pfEqual);
|
||||||
|
|
||||||
if(!pfEqual)
|
if(!pfEqual)
|
||||||
@ -3705,10 +3820,18 @@ static HRESULT WINAPI Uri_IsEqual(IUri *iface, IUri *pUri, BOOL *pfEqual)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
FIXME("(%p)->(%p %p)\n", This, pUri, pfEqual);
|
/* Try to convert it to a Uri (allows for a more simple comparison). */
|
||||||
|
if((other = get_uri_obj(pUri)))
|
||||||
|
*pfEqual = are_equal_simple(This, other);
|
||||||
|
else {
|
||||||
|
/* Do it the hard way. */
|
||||||
|
FIXME("(%p)->(%p %p) No support for unknown IUri's yet.\n", iface, pUri, pfEqual);
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
#undef URI_THIS
|
#undef URI_THIS
|
||||||
|
|
||||||
static const IUriVtbl UriVtbl = {
|
static const IUriVtbl UriVtbl = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user