зеркало из https://github.com/mozilla/pjs.git
Use nsIFile::Equals to implement Equals for two nsStandardURLs that are both
file urls. Bug 127373, r+sr=darin
This commit is contained in:
Родитель
4ccb583022
Коммит
718d9f9e5b
|
@ -53,6 +53,7 @@
|
|||
#include "nsIIDNService.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "prlog.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
static NS_DEFINE_CID(kThisImplCID, NS_THIS_STANDARDURL_IMPL_CID);
|
||||
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
|
||||
|
@ -638,25 +639,6 @@ nsStandardURL::BuildNormalizedSpec(const char *spec)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsStandardURL::HostsAreEquivalent(nsStandardURL *that)
|
||||
{
|
||||
// XXX now that hostnames are always normalized this special casing
|
||||
// may be unnecessary. we should be able to directly compare the
|
||||
// contents of mSpec.
|
||||
|
||||
// optimize for the non-IDN case...
|
||||
if ((this->mHostEncoding == eEncoding_ASCII) &&
|
||||
(that->mHostEncoding == eEncoding_ASCII))
|
||||
return SegmentIs(mHost, that->mSpec.get(), that->mHost);
|
||||
|
||||
nsCAutoString thisHost, thatHost;
|
||||
this->GetAsciiHost(thisHost);
|
||||
that->GetAsciiHost(thatHost);
|
||||
|
||||
return !nsCRT::strcasecmp(thisHost.get(), thatHost.get());
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsStandardURL::SegmentIs(const URLSegment &seg, const char *val)
|
||||
{
|
||||
|
@ -667,7 +649,7 @@ nsStandardURL::SegmentIs(const URLSegment &seg, const char *val)
|
|||
return PR_FALSE;
|
||||
// if the first |seg.mLen| chars of |val| match, then |val| must
|
||||
// also be null terminated at |seg.mLen|.
|
||||
return !nsCRT::strncasecmp(mSpec.get() + seg.mPos, val, seg.mLen)
|
||||
return !strncmp(mSpec.get() + seg.mPos, val, seg.mLen)
|
||||
&& (val[seg.mLen] == '\0');
|
||||
}
|
||||
|
||||
|
@ -681,7 +663,7 @@ nsStandardURL::SegmentIs(const char* spec, const URLSegment &seg, const char *va
|
|||
return PR_FALSE;
|
||||
// if the first |seg.mLen| chars of |val| match, then |val| must
|
||||
// also be null terminated at |seg.mLen|.
|
||||
return !nsCRT::strncasecmp(spec + seg.mPos, val, seg.mLen)
|
||||
return !strncmp(spec + seg.mPos, val, seg.mLen)
|
||||
&& (val[seg.mLen] == '\0');
|
||||
}
|
||||
|
||||
|
@ -692,7 +674,7 @@ nsStandardURL::SegmentIs(const URLSegment &seg1, const char *val, const URLSegme
|
|||
return PR_FALSE;
|
||||
if (seg1.mLen == -1 || (!val && mSpec.IsEmpty()))
|
||||
return PR_TRUE; // both are empty
|
||||
return !nsCRT::strncasecmp(mSpec.get() + seg1.mPos, val + seg2.mPos, seg1.mLen);
|
||||
return !strncmp(mSpec.get() + seg1.mPos, val + seg2.mPos, seg1.mLen);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
|
@ -1383,6 +1365,10 @@ nsStandardURL::SetHost(const nsACString &input)
|
|||
mAuthority.mLen += shift;
|
||||
ShiftFromPath(shift);
|
||||
}
|
||||
|
||||
// Now canonicalize the host to lowercase
|
||||
net_ToLowerCase(mSpec.BeginWriting() + mHost.mPos, mHost.mLen);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1475,22 +1461,55 @@ nsStandardURL::Equals(nsIURI *unknownOther, PRBool *result)
|
|||
NS_ENSURE_ARG_POINTER(unknownOther);
|
||||
NS_PRECONDITION(result, "null pointer");
|
||||
|
||||
nsStandardURL *other;
|
||||
nsresult rv = unknownOther->QueryInterface(kThisImplCID, (void **) &other);
|
||||
nsRefPtr<nsStandardURL> other;
|
||||
nsresult rv = unknownOther->QueryInterface(kThisImplCID,
|
||||
getter_AddRefs(other));
|
||||
if (NS_FAILED(rv)) {
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// XXX this needs to allow for case insensitive paths in some cases (e.g.,
|
||||
// file: URLs under windows).
|
||||
// First, check whether both URIs are nsIFileURLs. If they are, compare
|
||||
// the nsIFiles, since that will do case things appropriately for the OS
|
||||
// we're running on.
|
||||
if (mSupportsFileURL != other->mSupportsFileURL) {
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mSupportsFileURL) {
|
||||
// Assume not equal for failure cases... but failures in GetFile are
|
||||
// really failures, so propagate them to caller.
|
||||
*result = PR_FALSE;
|
||||
|
||||
if (!SegmentIs(mScheme, other->mSpec.get(), other->mScheme)) {
|
||||
// No need to compare files -- these are different beasties
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = EnsureFile();
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("nsStandardURL::Equals [this=%p spec=%s] failed to ensure file",
|
||||
this, mSpec.get()));
|
||||
return rv;
|
||||
}
|
||||
NS_ASSERTION(mFile, "EnsureFile() lied!");
|
||||
rv = other->EnsureFile();
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("nsStandardURL::Equals [other=%p spec=%s] other failed to ensure file",
|
||||
other, other->mSpec.get()));
|
||||
return rv;
|
||||
}
|
||||
NS_ASSERTION(other->mFile, "EnsureFile() lied!");
|
||||
return mFile->Equals(other->mFile, result);
|
||||
}
|
||||
|
||||
*result =
|
||||
SegmentIs(mScheme, other->mSpec.get(), other->mScheme) &&
|
||||
SegmentIs(mDirectory, other->mSpec.get(), other->mDirectory) &&
|
||||
SegmentIs(mBasename, other->mSpec.get(), other->mBasename) &&
|
||||
SegmentIs(mExtension, other->mSpec.get(), other->mExtension) &&
|
||||
HostsAreEquivalent(other) &&
|
||||
SegmentIs(mHost, other->mSpec.get(), other->mHost) &&
|
||||
SegmentIs(mQuery, other->mSpec.get(), other->mQuery) &&
|
||||
SegmentIs(mRef, other->mSpec.get(), other->mRef) &&
|
||||
SegmentIs(mUsername, other->mSpec.get(), other->mUsername) &&
|
||||
|
@ -1498,7 +1517,6 @@ nsStandardURL::Equals(nsIURI *unknownOther, PRBool *result)
|
|||
SegmentIs(mParam, other->mSpec.get(), other->mParam) &&
|
||||
(Port() == other->Port());
|
||||
|
||||
NS_RELEASE(other);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1740,7 +1758,7 @@ nsStandardURL::GetCommonBaseSpec(nsIURI *uri2, nsACString &aResult)
|
|||
nsresult rv = uri2->QueryInterface(kThisImplCID, (void **) &stdurl2);
|
||||
isEquals = NS_SUCCEEDED(rv)
|
||||
&& SegmentIs(mScheme, stdurl2->mSpec.get(), stdurl2->mScheme)
|
||||
&& HostsAreEquivalent(stdurl2)
|
||||
&& SegmentIs(mHost, stdurl2->mSpec.get(), stdurl2->mHost)
|
||||
&& SegmentIs(mUsername, stdurl2->mSpec.get(), stdurl2->mUsername)
|
||||
&& SegmentIs(mPassword, stdurl2->mSpec.get(), stdurl2->mPassword)
|
||||
&& (Port() == stdurl2->Port());
|
||||
|
@ -2257,24 +2275,39 @@ nsStandardURL::SetFileExtension(const nsACString &input)
|
|||
// nsStandardURL::nsIFileURL
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsStandardURL::EnsureFile()
|
||||
{
|
||||
NS_PRECONDITION(mSupportsFileURL,
|
||||
"EnsureFile() called on a URL that doesn't support files!");
|
||||
if (mFile) {
|
||||
// Nothing to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Parse the spec if we don't have a cached result
|
||||
if (mSpec.IsEmpty()) {
|
||||
NS_ERROR("url not initialized");
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (!SegmentIs(mScheme, "file")) {
|
||||
NS_ERROR("not a file URL");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return net_GetFileFromURLSpec(mSpec, getter_AddRefs(mFile));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStandardURL::GetFile(nsIFile **result)
|
||||
{
|
||||
// reparse the spec if we don't have a cached result
|
||||
if (!mFile) {
|
||||
if (mSpec.IsEmpty()) {
|
||||
NS_ERROR("url not initialized");
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
NS_PRECONDITION(mSupportsFileURL,
|
||||
"GetFile() called on a URL that doesn't support files!");
|
||||
nsresult rv = EnsureFile();
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!SegmentIs(mScheme, "file")) {
|
||||
NS_ERROR("not a file URL");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv = net_GetFileFromURLSpec(mSpec, getter_AddRefs(mFile));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
if (LOG_ENABLED()) {
|
||||
|
|
|
@ -143,6 +143,11 @@ public: /* internal -- HPUX compiler can't handle this being private */
|
|||
protected:
|
||||
virtual nsStandardURL* StartClone();
|
||||
|
||||
// Helper for subclass implementation of GetFile(). Subclasses that map
|
||||
// URIs to files in a special way should implement this method. It should
|
||||
// ensure that our mFile is initialized, if it's possible.
|
||||
virtual nsresult EnsureFile();
|
||||
|
||||
private:
|
||||
PRInt32 Port() { return mPort == -1 ? mDefaultPort : mPort; }
|
||||
|
||||
|
@ -158,8 +163,6 @@ private:
|
|||
|
||||
nsresult BuildNormalizedSpec(const char *spec);
|
||||
|
||||
PRBool HostsAreEquivalent(nsStandardURL *other);
|
||||
|
||||
PRBool SegmentIs(const URLSegment &s1, const char *val);
|
||||
PRBool SegmentIs(const char* spec, const URLSegment &s1, const char *val);
|
||||
PRBool SegmentIs(const URLSegment &s1, const char *val, const URLSegment &s2);
|
||||
|
@ -234,7 +237,12 @@ private:
|
|||
|
||||
nsCString mOriginCharset;
|
||||
nsCOMPtr<nsIURLParser> mParser;
|
||||
|
||||
// mFile is protected so subclasses can access it directly
|
||||
protected:
|
||||
nsCOMPtr<nsIFile> mFile; // cached result for nsIFileURL::GetFile
|
||||
|
||||
private:
|
||||
char *mHostA; // cached result for nsIURI::GetHostA
|
||||
|
||||
enum {
|
||||
|
|
|
@ -76,8 +76,8 @@ static PRLogModuleInfo *gResLog;
|
|||
// nsResURL : overrides nsStandardURL::GetFile to provide nsIFile resolution
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsResURL::GetFile(nsIFile **result)
|
||||
nsresult
|
||||
nsResURL::EnsureFile()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
|
@ -87,11 +87,11 @@ nsResURL::GetFile(nsIFile **result)
|
|||
rv = gResHandler->ResolveURI(this, spec);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = net_GetFileFromURLSpec(spec, result);
|
||||
rv = net_GetFileFromURLSpec(spec, getter_AddRefs(mFile));
|
||||
#ifdef DEBUG_bsmedberg
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool exists = PR_TRUE;
|
||||
(*result)->Exists(&exists);
|
||||
mFile->Exists(&exists);
|
||||
if (!exists) {
|
||||
printf("resource %s doesn't exist!\n", spec.get());
|
||||
}
|
||||
|
|
|
@ -52,8 +52,8 @@ class nsResURL : public nsStandardURL
|
|||
{
|
||||
public:
|
||||
nsResURL() : nsStandardURL(PR_TRUE) {}
|
||||
NS_IMETHOD GetFile(nsIFile **);
|
||||
virtual nsStandardURL* StartClone();
|
||||
virtual nsresult EnsureFile();
|
||||
NS_IMETHOD GetClassIDNoAlloc(nsCID *aCID);
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче