Bug 27971. Better strategy for resource: urls to use less memory. Saves about 0.4% of entire run just bring up one page (home.mozilla.org). r=waterson

This commit is contained in:
warren%netscape.com 2000-06-09 07:51:13 +00:00
Родитель d457cdec7b
Коммит 0063d9a736
11 изменённых файлов: 250 добавлений и 224 удалений

Просмотреть файл

@ -1315,6 +1315,9 @@ NS_IMETHODIMP nsChromeRegistry::GetSelectedLocale(const PRUnichar *aPackageName,
return rv;
}
if (mChromeDataSource == nsnull)
return NS_ERROR_NULL_POINTER;
// Follow the "selectedLocale" arc.
nsCOMPtr<nsIRDFNode> selectedProvider;
if (NS_FAILED(rv = mChromeDataSource->GetTarget(resource, mSelectedLocale, PR_TRUE, getter_AddRefs(selectedProvider)))) {

Просмотреть файл

@ -1038,16 +1038,16 @@ nsStdURL::SetFile(nsIFile * aFile)
while (*s)
{
#ifndef XP_OS2
// We need to call IsDBCSLeadByte because
// Japanese windows can have 0x5C in the sencond byte
// of a Japanese character, for example 0x8F 0x5C is
// one Japanese character
if(::IsDBCSLeadByte(*s) && *(s+1) != nsnull) {
s++;
// We need to call IsDBCSLeadByte because
// Japanese windows can have 0x5C in the sencond byte
// of a Japanese character, for example 0x8F 0x5C is
// one Japanese character
if(::IsDBCSLeadByte(*s) && *(s+1) != nsnull) {
s++;
} else
#endif
if (*s == '\\')
*s = '/';
if (*s == '\\')
*s = '/';
s++;
}
#endif
@ -1057,8 +1057,14 @@ nsStdURL::SetFile(nsIFile * aFile)
#endif
// Escape the path with the directory mask
rv = nsURLEscape(ePath,nsIIOService::url_Directory+
nsIIOService::url_Forced,escPath);
nsIIOService::url_Forced,escPath);
if (NS_SUCCEEDED(rv)) {
PRBool dir;
rv = aFile->IsDirectory(&dir);
if (NS_SUCCEEDED(rv) && dir && escPath[escPath.Length() - 1] != '/') {
// make sure we have a trailing slash
escPath += "/";
}
rv = SetPath(escPath.GetBuffer());
}
}

Просмотреть файл

@ -23,7 +23,7 @@
#include "nsIProtocolHandler.idl"
interface nsISimpleEnumerator;
native nsCStringArrayPtr(nsCStringArray*);
interface nsISupportsArray;
%{C++
#include "nsVoidArray.h"
@ -65,10 +65,10 @@ interface nsIResProtocolHandler : nsIProtocolHandler
void removeSubstitution(in string root, in string url);
/**
* Returns a string array containing all substitutions currently
* registered for the root. This array is a snapshot of the
* Returns an nsISupportsArray of nsIURIs containing all substitutions
* currently registered for the root. This array is a snapshot of the
* registered entries so it can be iterated over without fear of
* thread-safety concerns.
*/
[noscript] nsCStringArrayPtr getSubstitutions(in string root);
nsISupportsArray getSubstitutions(in string root);
};

Просмотреть файл

@ -80,7 +80,6 @@ nsResChannel::nsResChannel()
nsresult
nsResChannel::Init(nsIResProtocolHandler* handler, nsIURI* uri)
{
mResolvedURI = uri;
mHandler = handler;
mResourceURI = uri;
return NS_OK;
@ -124,32 +123,24 @@ nsResChannel::Substitutions::Init()
char* root;
rv = channel->mResourceURI->GetHost(&root);
if (NS_SUCCEEDED(rv)) {
rv = channel->mHandler->GetSubstitutions(root, &mSubstitutions);
rv = channel->mHandler->GetSubstitutions(root, getter_AddRefs(mSubstitutions));
nsCRT::free(root);
}
return rv;
}
nsresult
nsResChannel::Substitutions::Next(nsIURI* *result)
nsResChannel::Substitutions::Next(char* *result)
{
nsresult rv;
nsResChannel* channel = GET_SUBSTITUTIONS_CHANNEL(this);
nsCString* str = (nsCString*)mSubstitutions->CStringAt(0);
if (str == nsnull) return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> resolvedURI;
rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull,
NS_GET_IID(nsIURI),
getter_AddRefs(resolvedURI));
nsCOMPtr<nsIURI> substURI;
rv = mSubstitutions->GetElementAt(mCurrentIndex++, getter_AddRefs(substURI));
if (NS_FAILED(rv)) return rv;
rv = resolvedURI->SetSpec(str->GetBuffer());
if (NS_FAILED(rv)) return rv;
PRBool ok = mSubstitutions->RemoveCStringAt(0);
if (!ok) return NS_ERROR_FAILURE;
if (substURI == nsnull)
return NS_ERROR_FAILURE;
char* path = nsnull;
rv = channel->mResourceURI->GetPath(&path);
@ -157,17 +148,12 @@ nsResChannel::Substitutions::Next(nsIURI* *result)
// XXX this path[0] check is a hack -- it seems to me that GetPath
// shouldn't include the leading slash:
nsXPIDLCString aResolvedURI;
rv = resolvedURI->Resolve(path[0] == '/' ? path+1 : path,
getter_Copies(aResolvedURI));
char* aResolvedURI;
rv = substURI->Resolve(path[0] == '/' ? path+1 : path, &aResolvedURI);
nsCRT::free(path);
if (NS_FAILED(rv)) return rv;
rv = resolvedURI->SetSpec(aResolvedURI);
if (NS_FAILED(rv)) return rv;
*result = resolvedURI;
NS_IF_ADDREF(*result);
*result = aResolvedURI;
return NS_OK;
}
@ -204,7 +190,7 @@ nsResChannel::Cancel(nsresult status)
rv = mResolvedChannel->Cancel(status);
}
mStatus = status;
mResolvedURI = mResourceURI; // remove the resolution
mResolvedChannel = nsnull; // remove the resolution
return rv;
}
@ -254,9 +240,10 @@ nsResChannel::SetOriginalURI(nsIURI* aURI)
NS_IMETHODIMP
nsResChannel::GetURI(nsIURI* *aURI)
{
if (mResolvedURI == nsnull)
mResolvedURI = mResourceURI;
*aURI = mResolvedURI;
if (mResolvedChannel) {
return mResolvedChannel->GetURI(aURI);
}
*aURI = mResourceURI;
NS_ADDREF(*aURI);
return NS_OK;
}
@ -271,15 +258,16 @@ nsresult
nsResChannel::EnsureNextResolvedChannel()
{
nsresult rv;
nsXPIDLCString resolvedURI;
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) goto done;
rv = mSubstitutions.Next(getter_AddRefs(mResolvedURI));
rv = mSubstitutions.Next(getter_Copies(resolvedURI));
if (NS_FAILED(rv)) goto done;
rv = serv->NewChannelFromURI(mResolvedURI,
getter_AddRefs(mResolvedChannel));
rv = serv->NewChannel(resolvedURI, nsnull,
getter_AddRefs(mResolvedChannel));
if (NS_FAILED(rv)) {
rv = NS_OK; // returning NS_OK lets us try again
goto done;
@ -322,15 +310,12 @@ nsResChannel::EnsureNextResolvedChannel()
#if defined(PR_LOGGING)
nsXPIDLCString resURI;
(void)mResourceURI->GetSpec(getter_Copies(resURI));
nsXPIDLCString newURI;
if (mResolvedURI)
(void)mResolvedURI->GetSpec(getter_Copies(newURI));
PR_LOG(gResChannelLog, PR_LOG_DEBUG,
("nsResChannel: resolving %s ",
(const char*)resURI));
PR_LOG(gResChannelLog, PR_LOG_DEBUG,
(" to %s => status %x\n",
(const char*)newURI, rv));
(const char*)resolvedURI, rv));
#endif /* PR_LOGGING */
return rv;
}

Просмотреть файл

@ -30,6 +30,7 @@
#include "nsIInterfaceRequestor.h"
#include "nsILoadGroup.h"
#include "nsIInputStream.h"
#include "nsISupportsArray.h"
#include "nsCOMPtr.h"
#include "nsAutoLock.h"
#ifdef DEBUG
@ -59,19 +60,15 @@ public:
protected:
class Substitutions {
public:
Substitutions() : mSubstitutions(nsnull) {}
~Substitutions(){
if (mSubstitutions) {
delete mSubstitutions;
mSubstitutions = nsnull;
}
}
Substitutions() : mCurrentIndex(0) {}
~Substitutions() {}
nsresult Init();
nsresult Next(nsIURI* *result);
nsresult Next(char* *result);
protected:
nsCOMPtr<nsIURI> mResourceURI;
nsCStringArray* mSubstitutions;
nsCOMPtr<nsISupportsArray> mSubstitutions;
PRUint32 mCurrentIndex;
};
friend class Substitutions;
@ -100,7 +97,6 @@ protected:
protected:
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mResourceURI;
nsCOMPtr<nsIURI> mResolvedURI;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
PRUint32 mLoadAttributes;
nsCOMPtr<nsILoadGroup> mLoadGroup;

Просмотреть файл

@ -37,14 +37,17 @@
#include "nsResProtocolHandler.h"
#include "nsAutoLock.h"
#include "nsIURL.h"
#include "nsIComponentManager.h"
#include "nsIIOService.h"
#include "nsIServiceManager.h"
#include "nsResChannel.h"
#include "prenv.h"
#include "prmem.h"
#include "prprf.h"
#include "nsXPIDLString.h"
#include "nsIFile.h"
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
@ -55,12 +58,27 @@ nsResProtocolHandler::nsResProtocolHandler()
}
nsresult
nsResProtocolHandler::SetSpecialDir(const char* name, nsSpecialSystemDirectory::SystemDirectories sysDir)
nsResProtocolHandler::SetSpecialDir(const char* rootName, const char* sysDir)
{
nsSpecialSystemDirectory dir(sysDir);
nsFileURL fileURL(dir);
nsresult rv;
nsCOMPtr<nsIFile> file;
rv = NS_GetSpecialDirectory(sysDir, getter_AddRefs(file));
if (NS_FAILED(rv)) return rv;
return AppendSubstitution(name, fileURL.GetURLString());
nsCOMPtr<nsIFileURL> fileURL;
rv = nsComponentManager::CreateInstance(kStandardURLCID, nsnull,
NS_GET_IID(nsIFileURL),
getter_AddRefs(fileURL));
if (NS_FAILED(rv)) return rv;
rv = fileURL->SetFile(file);
if (NS_FAILED(rv)) return rv;
nsXPIDLCString spec;
rv = fileURL->GetSpec(getter_Copies(spec));
if (NS_FAILED(rv)) return rv;
return AppendSubstitution(rootName, spec);
}
nsresult
@ -73,36 +91,36 @@ nsResProtocolHandler::Init()
return NS_ERROR_OUT_OF_MEMORY;
// set up initial mappings
rv = SetSpecialDir("ProgramDir", nsSpecialSystemDirectory::Moz_BinDirectory);
rv = SetSpecialDir("ProgramDir", "system.OS_CurrentProcessDirectory");
if (NS_FAILED(rv)) return rv;
// make "res:///" == "resource:/"
rv = SetSpecialDir("", nsSpecialSystemDirectory::Moz_BinDirectory);
rv = SetSpecialDir("", "system.OS_CurrentProcessDirectory");
if (NS_FAILED(rv)) return rv;
rv = SetSpecialDir("CurrentDir", nsSpecialSystemDirectory::OS_CurrentWorkingDirectory);
rv = SetSpecialDir("CurrentDir", "system.OS_CurrentWorkingDirectory");
if (NS_FAILED(rv)) return rv;
rv = SetSpecialDir("CurrentDrive", nsSpecialSystemDirectory::OS_DriveDirectory);
rv = SetSpecialDir("CurrentDrive", "system.OS_DriveDirectory");
if (NS_FAILED(rv)) return rv;
rv = SetSpecialDir("TempDir", nsSpecialSystemDirectory::OS_TemporaryDirectory);
rv = SetSpecialDir("TempDir", "system.OS_TemporaryDirectory");
if (NS_FAILED(rv)) return rv;
rv = SetSpecialDir("ComponentsDir", nsSpecialSystemDirectory::XPCOM_CurrentProcessComponentDirectory);
rv = SetSpecialDir("ComponentsDir", "xpcom.currentProcess.componentDirectory");
if (NS_FAILED(rv)) return rv;
rv = SetSpecialDir("SystemDir",
#ifdef XP_MAC
nsSpecialSystemDirectory::Mac_SystemDirectory
"system.SystemDirectory"
#elif XP_OS2
nsSpecialSystemDirectory::OS2_SystemDirectory
"system.SystemDirectory"
#elif XP_PC
nsSpecialSystemDirectory::Win_SystemDirectory
"system.SystemDirectory"
#elif XP_BEOS
nsSpecialSystemDirectory::BeOS_SystemDirectory
"system.SystemDirectory"
#else
nsSpecialSystemDirectory::Unix_LibDirectory // XXX ???
"system.LibDirectory" // XXX ???
#endif
);
if (NS_FAILED(rv)) return rv;
@ -110,78 +128,16 @@ nsResProtocolHandler::Init()
// Set up the "Resource" root to point to the old resource location
// such that:
// resource://<path> == res://Resource/<path>
#ifdef XP_PC
// XXX why is this one inconsistent -- Mac Unix and BeOS seem to look inthe current process dir
rv = SetSpecialDir("Resource", nsSpecialSystemDirectory::XPCOM_CurrentProcessComponentRegistry);
rv = SetSpecialDir("Resource", "system.OS_CurrentProcessDirectory");
if (NS_FAILED(rv)) return rv;
#elif defined (XP_MAC)
rv = SetSpecialDir("Resource", nsSpecialSystemDirectory::OS_CurrentProcessDirectory);
if (NS_FAILED(rv)) return rv;
#elif defined(XP_UNIX)
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024 // A good guess, i suppose
#endif
// first add $MOZILLA_FIVE_HOME if it exists
char* path = PR_GetEnv("MOZILLA_FIVE_HOME");
if (path) {
char* fileURL = PR_smprintf("file:///%s", path);
rv = AppendSubstitution("Resource", fileURL);
PR_Free(fileURL);
if (NS_FAILED(rv)) return rv;
}
// then add pwd
char homepath[MAXPATHLEN];
FILE* pp;
if (!(pp = popen("pwd", "r"))) {
NS_WARNING("res protocol: can't open pwd");
return NS_ERROR_FAILURE;
}
if (fgets(homepath, MAXPATHLEN, pp)) {
homepath[PL_strlen(homepath)-1] = 0;
}
else {
NS_WARNING("res protocol: can't get homepath");
pclose(pp);
return NS_ERROR_FAILURE;
}
pclose(pp);
char* fileURL = PR_smprintf("file:///%s", homepath);
rv = AppendSubstitution("Resource", fileURL);
PR_Free(fileURL);
if (NS_FAILED(rv)) return rv;
#elif defined(XP_BEOS)
rv = SetSpecialDir("Resource", nsSpecialSystemDirectory::XPCOM_CurrentProcessComponentRegistry);
if (NS_FAILED(rv)) return rv;
#endif
return rv;
}
static PRBool PR_CALLBACK
DeleteCStringArray(nsHashKey *aKey, void *aData, void* closure)
{
nsCStringArray* array = NS_STATIC_CAST(nsCStringArray*, aData);
if (array)
delete array;
return PR_TRUE;
}
nsResProtocolHandler::~nsResProtocolHandler()
{
if (mLock)
PR_DestroyLock(mLock);
mSubstitutions.Enumerate(DeleteCStringArray, nsnull);
}
NS_IMPL_THREADSAFE_ISUPPORTS2(nsResProtocolHandler, nsIResProtocolHandler, nsIProtocolHandler)
@ -277,97 +233,150 @@ nsResProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result)
////////////////////////////////////////////////////////////////////////////////
nsresult
nsResProtocolHandler::RawGetSubstitutions(const char *root, nsCStringArray* *result)
NS_IMETHODIMP
nsResProtocolHandler::PrependSubstitution(const char *root, const char *urlStr)
{
nsresult rv;
nsAutoLock lock(mLock);
nsCOMPtr<nsIIOService> ioServ = do_GetService(kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> url;
rv = ioServ->NewURI(urlStr, nsnull, getter_AddRefs(url));
if (NS_FAILED(rv)) return rv;
nsStringKey key(root);
nsCStringArray* strings = (nsCStringArray*)mSubstitutions.Get(&key);
nsCOMPtr<nsISupportsArray> strings;
nsCOMPtr<nsISupportsArray> newStrings;
strings = getter_AddRefs((nsISupportsArray*)mSubstitutions.Get(&key));
if (strings) {
// we have to snapshot the array when inserting a new element because
// someone could be iterating over the existing array
rv = strings->Clone(getter_AddRefs(newStrings));
if (NS_FAILED(rv)) return rv;
}
else {
rv = NS_NewISupportsArray(getter_AddRefs(newStrings));
if (NS_FAILED(rv)) return rv;
}
rv = newStrings->InsertElementAt(url, 0) ? NS_OK : NS_ERROR_FAILURE;
if (NS_SUCCEEDED(rv)) {
// replace existing array
(void)mSubstitutions.Put(&key, newStrings);
}
return rv;
}
NS_IMETHODIMP
nsResProtocolHandler::AppendSubstitution(const char *root, const char *urlStr)
{
nsresult rv;
nsAutoLock lock(mLock);
nsCOMPtr<nsIIOService> ioServ = do_GetService(kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> url;
rv = ioServ->NewURI(urlStr, nsnull, getter_AddRefs(url));
if (NS_FAILED(rv)) return rv;
nsStringKey key(root);
nsCOMPtr<nsISupportsArray> strings;
nsCOMPtr<nsISupportsArray> newStrings;
strings = getter_AddRefs((nsISupportsArray*)mSubstitutions.Get(&key));
if (strings) {
// we have to snapshot the array when inserting a new element because
// someone could be iterating over the existing array
rv = strings->Clone(getter_AddRefs(newStrings));
if (NS_FAILED(rv)) return rv;
}
else {
rv = NS_NewISupportsArray(getter_AddRefs(newStrings));
if (NS_FAILED(rv)) return rv;
}
rv = newStrings->AppendElement(url) ? NS_OK : NS_ERROR_FAILURE;
if (NS_SUCCEEDED(rv)) {
// replace existing array
(void)mSubstitutions.Put(&key, newStrings);
}
return rv;
}
struct CopyMostArgs {
nsISupportsArray* mNewArray;
nsIURI* mRemoveURL;
};
static PRBool
CopyMost(nsISupports* aElement, void *aData)
{
nsresult rv = NS_OK;
CopyMostArgs* args = (CopyMostArgs*)aData;
nsIURI* thisURL = (nsIURI*)aElement;
PRBool eq;
rv = thisURL->Equals(args->mRemoveURL, &eq);
if (NS_FAILED(rv)) return PR_FALSE;
if (!eq) {
rv = args->mNewArray->AppendElement(thisURL) ? NS_OK : NS_ERROR_FAILURE;
}
return NS_SUCCEEDED(rv);
}
NS_IMETHODIMP
nsResProtocolHandler::RemoveSubstitution(const char *root, const char *urlStr)
{
nsresult rv;
nsAutoLock lock(mLock);
nsCOMPtr<nsIIOService> ioServ = do_GetService(kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> url;
rv = ioServ->NewURI(urlStr, nsnull, getter_AddRefs(url));
if (NS_FAILED(rv)) return rv;
nsStringKey key(root);
nsCOMPtr<nsISupportsArray> strings;
nsCOMPtr<nsISupportsArray> newStrings;
strings = getter_AddRefs((nsISupportsArray*)mSubstitutions.Get(&key));
if (strings == nsnull) {
strings = new nsCStringArray();
if (strings == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
// can't remove element if it doesn't exist
return NS_ERROR_FAILURE;
}
rv = NS_NewISupportsArray(getter_AddRefs(newStrings));
if (NS_FAILED(rv)) return rv;
CopyMostArgs args;
args.mNewArray = newStrings;
args.mRemoveURL = url;
PRBool ok = strings->EnumerateForwards(CopyMost, &args);
rv = ok ? NS_OK : NS_ERROR_FAILURE;
if (NS_SUCCEEDED(rv)) {
// replace existing array
(void)mSubstitutions.Put(&key, newStrings);
}
return rv;
}
NS_IMETHODIMP
nsResProtocolHandler::GetSubstitutions(const char *root, nsISupportsArray* *result)
{
nsresult rv;
nsAutoLock lock(mLock);
nsStringKey key(root);
nsISupportsArray* strings = (nsISupportsArray*)mSubstitutions.Get(&key);
if (strings == nsnull) {
rv = NS_NewISupportsArray(&strings);
if (NS_FAILED(rv)) return rv;
(void)mSubstitutions.Put(&key, strings);
}
*result = strings;
return NS_OK;
}
NS_IMETHODIMP
nsResProtocolHandler::PrependSubstitution(const char *root, const char *url)
{
nsresult rv;
nsAutoLock lock(mLock);
nsCStringArray* strings;
rv = RawGetSubstitutions(root, &strings);
if (NS_FAILED(rv)) return rv;
nsCString urlStr(url);
PRBool ok = strings->InsertCStringAt(urlStr, 0);
if (!ok) return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP
nsResProtocolHandler::AppendSubstitution(const char *root, const char *url)
{
nsresult rv;
nsAutoLock lock(mLock);
nsCStringArray* strings;
rv = RawGetSubstitutions(root, &strings);
if (NS_FAILED(rv)) return rv;
nsCString urlStr(url);
PRBool ok = strings->AppendCString(urlStr);
if (!ok) return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP
nsResProtocolHandler::RemoveSubstitution(const char *root, const char *url)
{
nsresult rv;
nsAutoLock lock(mLock);
nsCStringArray* strings;
rv = RawGetSubstitutions(root, &strings);
if (NS_FAILED(rv)) return rv;
nsCString urlStr(url);
PRBool ok = strings->RemoveCString(urlStr);
if (!ok) return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP
nsResProtocolHandler::GetSubstitutions(const char *root, nsCStringArray* *result)
{
nsresult rv;
nsAutoLock lock(mLock);
nsCStringArray* strings;
rv = RawGetSubstitutions(root, &strings);
if (NS_FAILED(rv)) return rv;
// XXX should put this in nsCStringArray::Clone
nsCStringArray* subst = new nsCStringArray();
if (subst == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
PRInt32 len = strings->Count();
for (PRInt32 i = 0; i < len; i++) {
PRBool ok = subst->AppendCString(*(*strings)[i]);
if (!ok) {
delete subst;
return NS_ERROR_FAILURE;
}
}
*result = subst;
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -25,7 +25,7 @@
#include "nsIResProtocolHandler.h"
#include "nsHashtable.h"
#include "nsSpecialSystemDirectory.h"
#include "nsISupportsArray.h"
class nsResProtocolHandler : public nsIResProtocolHandler
{
@ -42,12 +42,11 @@ public:
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
nsresult Init();
nsresult SetSpecialDir(const char* name, nsSpecialSystemDirectory::SystemDirectories sysDir);
nsresult RawGetSubstitutions(const char *root, nsCStringArray* *result);
nsresult SetSpecialDir(const char* rootName, const char* specialDir);
protected:
PRLock* mLock;
nsHashtable mSubstitutions;
nsSupportsHashtable mSubstitutions;
};
#endif /* nsResProtocolHandler_h___ */

Просмотреть файл

@ -1315,6 +1315,9 @@ NS_IMETHODIMP nsChromeRegistry::GetSelectedLocale(const PRUnichar *aPackageName,
return rv;
}
if (mChromeDataSource == nsnull)
return NS_ERROR_NULL_POINTER;
// Follow the "selectedLocale" arc.
nsCOMPtr<nsIRDFNode> selectedProvider;
if (NS_FAILED(rv = mChromeDataSource->GetTarget(resource, mSelectedLocale, PR_TRUE, getter_AddRefs(selectedProvider)))) {

Просмотреть файл

@ -85,6 +85,8 @@ interface nsISupportsArray : nsICollection {
[notxpcom, noscript]
boolean EnumerateBackwards(in nsISupportsArrayEnumFunc aFunc,
in voidPtr aData);
nsISupportsArray clone();
%{C++
private:
// NS_IMETHOD_(nsISupportsArray&) operator=(const nsISupportsArray& other) = 0;

Просмотреть файл

@ -382,6 +382,27 @@ nsSupportsArray::Enumerate(nsIEnumerator* *result)
return NS_OK;
}
static PRBool
CopyElement(nsISupports* aElement, void *aData)
{
nsresult rv;
nsISupportsArray* newArray = (nsISupportsArray*)aData;
rv = newArray->AppendElement(aElement);
return NS_SUCCEEDED(rv);
}
NS_IMETHODIMP
nsSupportsArray::Clone(nsISupportsArray* *result)
{
nsresult rv;
nsISupportsArray* newArray;
rv = NS_NewISupportsArray(&newArray);
PRBool ok = EnumerateForwards(CopyElement, newArray);
if (!ok) return NS_ERROR_OUT_OF_MEMORY;
*result = newArray;
return NS_OK;
}
NS_COM nsresult
NS_NewISupportsArray(nsISupportsArray** aInstancePtrResult)
{

Просмотреть файл

@ -115,6 +115,8 @@ public:
NS_IMETHOD_(PRBool) EnumerateForwards(nsISupportsArrayEnumFunc aFunc, void* aData);
NS_IMETHOD_(PRBool) EnumerateBackwards(nsISupportsArrayEnumFunc aFunc, void* aData);
NS_IMETHOD Clone(nsISupportsArray **_retval);
protected:
NS_IMETHOD_(nsISupportsArray&) operator=(const nsISupportsArray& aOther);
NS_IMETHOD_(PRBool) operator==(const nsISupportsArray& aOther) { return Equals(&aOther); }