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:
bsmedberg%covad.net
2006-01-10 20:33:54 +00:00
parent e769e2a181
commit 9dbcbaa07f
4 changed files with 71 additions and 37 deletions

View File

@@ -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;
};

View File

@@ -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 \

View File

@@ -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;
}

View File

@@ -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);