Bug 320328 - Ts regression from bug 316416 (nsIModuleLoader) - cache the canonical (short) pathname (windows only), r=darin
git-svn-id: svn://10.0.0.236/trunk@187251 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -39,7 +39,7 @@
|
||||
|
||||
#include "nsILocalFile.idl"
|
||||
|
||||
[scriptable, uuid(dc42f467-4094-437d-9e3e-8912a072aede)]
|
||||
[scriptable, uuid(def38371-73b0-4dfd-85cd-0a7c91afbec6)]
|
||||
interface nsILocalFileWin : nsILocalFile
|
||||
{
|
||||
/**
|
||||
@@ -52,5 +52,17 @@ interface nsILocalFileWin : nsILocalFile
|
||||
*
|
||||
*/
|
||||
AString getVersionInfoField(in string aField);
|
||||
|
||||
/**
|
||||
* The canonical path of the file, which avoids short/long
|
||||
* pathname inconsistencies. The nsILocalFile persistent
|
||||
* descriptor is not guaranteed to be canonicalized (it may
|
||||
* persist either the long or the short path name). The format of
|
||||
* the canonical path will vary with the underlying file system:
|
||||
* it will typically be the short pathname on filesystems that
|
||||
* support both short and long path forms.
|
||||
*/
|
||||
readonly attribute AString canonicalPath;
|
||||
[noscript] readonly attribute ACString nativeCanonicalPath;
|
||||
};
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@
|
||||
#ifndef _NS_LOCAL_FILE_H_
|
||||
#define _NS_LOCAL_FILE_H_
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
#define NS_LOCAL_FILE_CID {0x2e23e220, 0x60be, 0x11d3, {0x8c, 0x4a, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74}}
|
||||
|
||||
#define NS_DECL_NSLOCALFILE_UNICODE_METHODS \
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "prtypes.h"
|
||||
#include "prio.h"
|
||||
#include "prprf.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsReadableUtils.h"
|
||||
@@ -452,7 +453,6 @@ NS_IMPL_ISUPPORTS2(nsDirEnumerator, nsISimpleEnumerator, nsIDirectoryEnumerator)
|
||||
nsLocalFile::nsLocalFile()
|
||||
: mDirty(PR_TRUE)
|
||||
, mFollowSymlinks(PR_FALSE)
|
||||
, mHashCode(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -495,7 +495,6 @@ nsLocalFile::nsLocalFile(const nsLocalFile& other)
|
||||
: mDirty(PR_TRUE)
|
||||
, mFollowSymlinks(other.mFollowSymlinks)
|
||||
, mWorkingPath(other.mWorkingPath)
|
||||
, mHashCode(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -2160,26 +2159,20 @@ nsLocalFile::Equals(nsIFile *inFile, PRBool *_retval)
|
||||
NS_ENSURE_ARG(inFile);
|
||||
NS_ENSURE_ARG(_retval);
|
||||
|
||||
EnsureShortPath();
|
||||
|
||||
nsCOMPtr<nsILocalFileWin> lf(do_QueryInterface(inFile));
|
||||
if (!lf) {
|
||||
*_retval = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCAutoString inFilePath;
|
||||
inFile->GetNativePath(inFilePath);
|
||||
lf->GetNativeCanonicalPath(inFilePath);
|
||||
|
||||
// Normalize both paths to the short form, failing back to a string
|
||||
// comparison of the long form.
|
||||
*_retval = _mbsicmp((unsigned char*) mShortWorkingPath.get(),
|
||||
(unsigned char*) inFilePath.get()) == 0;
|
||||
|
||||
char thisshort[MAX_PATH];
|
||||
char thatshort[MAX_PATH];
|
||||
|
||||
DWORD thisr = GetShortPathName(mWorkingPath.get(), thisshort, sizeof(thisshort));
|
||||
DWORD thatr = GetShortPathName(inFilePath.get(), thatshort, sizeof(thatshort));
|
||||
|
||||
if (thisr && thatr && thisr < sizeof(thisshort) && thatr < sizeof(thatshort)) {
|
||||
*_retval = (_mbsicmp((unsigned char*) thisshort,
|
||||
(unsigned char*) thatshort) == 0);
|
||||
}
|
||||
else {
|
||||
*_retval = (_mbsicmp((unsigned char*) inFilePath.get(),
|
||||
(unsigned char*) mWorkingPath.get()) == 0);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -2544,23 +2537,45 @@ nsLocalFile::Equals(nsIHashable* aOther, PRBool *aResult)
|
||||
return Equals(otherfile, aResult);
|
||||
}
|
||||
|
||||
void
|
||||
nsLocalFile::EnsureShortPath()
|
||||
{
|
||||
if (!mShortWorkingPath.IsEmpty())
|
||||
return;
|
||||
|
||||
char thisshort[MAX_PATH];
|
||||
DWORD thisr = GetShortPathName(mWorkingPath.get(),
|
||||
thisshort, sizeof(thisshort));
|
||||
if (thisr < sizeof(thisshort))
|
||||
mShortWorkingPath.Assign(thisshort);
|
||||
else
|
||||
mShortWorkingPath.Assign(mWorkingPath);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::GetNativeCanonicalPath(nsACString &aResult)
|
||||
{
|
||||
EnsureShortPath();
|
||||
aResult.Assign(mShortWorkingPath);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::GetCanonicalPath(nsAString &aResult)
|
||||
{
|
||||
EnsureShortPath();
|
||||
NS_CopyNativeToUnicode(mShortWorkingPath, aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLocalFile::GetHashCode(PRUint32 *aResult)
|
||||
{
|
||||
if (!mHashCode) {
|
||||
// In order for short and long path names to hash to the same value we
|
||||
// always hash on the short pathname.
|
||||
// In order for short and long path names to hash to the same value we
|
||||
// always hash on the short pathname.
|
||||
EnsureShortPath();
|
||||
|
||||
char thisshort[MAX_PATH];
|
||||
DWORD thisr = GetShortPathName(mWorkingPath.get(),
|
||||
thisshort, sizeof(thisshort));
|
||||
if (thisr < sizeof(thisshort))
|
||||
mHashCode = nsCRT::HashCode(thisshort);
|
||||
else
|
||||
mHashCode = nsCRT::HashCode(mWorkingPath.get());
|
||||
}
|
||||
|
||||
*aResult = mHashCode;
|
||||
*aResult = HashString(mShortWorkingPath);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
@@ -104,13 +104,18 @@ private:
|
||||
// this will be the resolved path of shortcuts, it will *NEVER* be returned to the user
|
||||
nsCString mResolvedPath;
|
||||
|
||||
PRFileInfo64 mFileInfo64;
|
||||
PRUint32 mHashCode;
|
||||
// this string, if not empty, is the *short* pathname that represents
|
||||
// mWorkingPath
|
||||
nsCString mShortWorkingPath;
|
||||
|
||||
void MakeDirty() { mDirty = PR_TRUE; mHashCode = 0; }
|
||||
PRFileInfo64 mFileInfo64;
|
||||
|
||||
void MakeDirty() { mDirty = PR_TRUE; mShortWorkingPath.Truncate(); }
|
||||
|
||||
nsresult ResolveAndStat();
|
||||
nsresult ResolveShortcut();
|
||||
|
||||
void EnsureShortPath();
|
||||
|
||||
nsresult CopyMove(nsIFile *newParentDir, const nsACString &newName, PRBool followSymlinks, PRBool move);
|
||||
nsresult CopySingleFile(nsIFile *source, nsIFile* dest, const nsACString &newName, PRBool followSymlinks, PRBool move);
|
||||
|
||||
Reference in New Issue
Block a user