gecko-dev/chrome/src/nsChromeRegistry.cpp

1834 lines
52 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
1999-04-02 00:52:35 +00:00
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
1999-04-02 00:52:35 +00:00
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
1999-04-02 00:52:35 +00:00
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
* Contributor(s):
* Original Author: David W. Hyatt (hyatt@netscape.com)
* Gagan Saksena <gagan@netscape.com>
* Benjamin Smedberg <benjamin@smedbergs.us>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
1999-04-02 00:52:35 +00:00
#include "nsChromeRegistry.h"
2000-05-13 21:42:56 +00:00
#include <string.h>
#include "prio.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsArrayEnumerator.h"
1999-04-02 00:52:35 +00:00
#include "nsCOMPtr.h"
#include "nsDOMError.h"
#include "nsEscape.h"
#include "nsInt64.h"
#include "nsLayoutCID.h"
#include "nsNetCID.h"
#include "nsNetUtil.h"
#include "nsReadableUtils.h"
#include "nsStaticAtom.h"
#include "nsString.h"
#include "nsWidgetsCID.h"
1999-04-02 00:52:35 +00:00
#include "nsXPIDLString.h"
#include "nsIAtom.h"
#include "nsIBindingManager.h"
#include "nsICommandLine.h"
#include "nsICSSLoader.h"
#include "nsICSSStyleSheet.h"
#include "nsIDirectoryService.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
2001-04-10 03:29:23 +00:00
#include "nsIDocShell.h"
1999-11-29 06:51:24 +00:00
#include "nsIDocumentObserver.h"
#include "nsIDOMElement.h"
#include "nsIDOMLocation.h"
#include "nsIDOMWindowCollection.h"
#include "nsIDOMWindowInternal.h"
#include "nsIFileChannel.h"
#include "nsIFileURL.h"
#include "nsIIOService.h"
#include "nsIJARURI.h"
#include "nsILocalFile.h"
#include "nsILocaleService.h"
#include "nsILookAndFeel.h"
#include "nsIObserverService.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIPrefBranchInternal.h"
#include "nsIPresShell.h"
#include "nsISimpleEnumerator.h"
#include "nsIStyleSheet.h"
#include "nsISupportsArray.h"
#include "nsIWindowMediator.h"
// keep all the RDF stuff together, in case we can remove it in the far future
#include "rdf.h"
#include "nsRDFCID.h"
#include "nsIRDFService.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFObserver.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsIRDFXMLSink.h"
#include "nsIServiceManager.h"
#include "nsIRDFResource.h"
#include "nsIRDFDataSource.h"
#include "nsIRDFContainer.h"
#include "nsIRDFContainerUtils.h"
#define UILOCALE_CMD_LINE_ARG "UILocale"
#define MATCH_OS_LOCALE_PREF "intl.locale.matchOS"
#define SELECTED_LOCALE_PREF "general.useragent.locale"
#define SELECTED_SKIN_PREF "general.skins.selectedSkin"
#define DSS_SKIN_TO_SELECT "extensions.lastSelectedSkin"
#define DSS_SWITCH_PENDING "extensions.dss.switchPending"
1999-04-02 00:52:35 +00:00
static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
1999-12-01 08:44:43 +00:00
nsChromeRegistry* gChromeRegistry;
#define CHROME_URI "http://www.mozilla.org/rdf/chrome#"
DEFINE_RDF_VOCAB(CHROME_URI, CHROME, packages);
DEFINE_RDF_VOCAB(CHROME_URI, CHROME, package);
2000-05-13 21:42:56 +00:00
DEFINE_RDF_VOCAB(CHROME_URI, CHROME, name);
DEFINE_RDF_VOCAB(CHROME_URI, CHROME, platformPackage);
1999-04-02 00:52:35 +00:00
////////////////////////////////////////////////////////////////////////////////
// We use a "best-fit" algorithm for matching locales and themes.
// 1) the exact selected locale/theme
// 2) (locales only) same language, different country
// e.g. en-GB is the selected locale, only en-US is available
// 3) any available locale/theme
/**
* Match the language-part of two lang-COUNTRY codes, hopefully but
* not guaranteed to be in the form ab-CD or abz-CD. "ab" should also
* work, any other garbage-in will produce undefined results as long
* as it does not crash.
*/
static PRBool
LanguagesMatch(const nsACString& a, const nsACString& b)
{
if (a.Length() < 2 || b.Length() < 2)
return PR_FALSE;
nsACString::const_iterator as, ae, bs, be;
a.BeginReading(as);
a.EndReading(ae);
b.BeginReading(bs);
b.EndReading(be);
while (*as == *bs) {
if (*as == '-')
return PR_TRUE;
// reached the end
if (as == ae && bs == be)
return PR_TRUE;
// "a" is short
if (as == ae)
return (*++bs == '-');
// "b" is short
if (bs == be)
return (*++as == '-');
++as; ++bs;
}
return PR_FALSE;
}
nsChromeRegistry::ProviderEntry*
nsChromeRegistry::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
{
PRInt32 i = mArray.Count();
if (!i)
return nsnull;
ProviderEntry* found = nsnull; // Only set if we find a partial-match locale
ProviderEntry* entry;
while (i--) {
entry = NS_REINTERPRET_CAST(ProviderEntry*, mArray[i]);
if (aPreferred.Equals(entry->provider))
return entry;
if (aType == LOCALE && !found && LanguagesMatch(aPreferred, entry->provider))
found = entry;
}
if (!found && aType != EXACT)
return entry;
return found;
}
nsIURI*
nsChromeRegistry::nsProviderArray::GetBase(const nsACString& aPreferred, MatchType aType)
{
ProviderEntry* provider = GetProvider(aPreferred, aType);
if (!provider)
return nsnull;
return provider->baseURI;
}
const nsACString&
nsChromeRegistry::nsProviderArray::GetSelected(const nsACString& aPreferred, MatchType aType)
{
ProviderEntry* entry = GetProvider(aPreferred, aType);
if (entry)
return entry->provider;
return EmptyCString();
}
void
nsChromeRegistry::nsProviderArray::SetBase(const nsACString& aProvider, nsIURI* aBaseURL)
{
ProviderEntry* provider = GetProvider(aProvider, EXACT);
if (provider) {
provider->baseURI = aBaseURL;
return;
}
// no existing entries, add a new one
provider = new ProviderEntry(aProvider, aBaseURL);
if (!provider)
return; // It's safe to silently fail on OOM
mArray.AppendElement(provider);
}
void
nsChromeRegistry::nsProviderArray::Clear()
{
PRInt32 i = mArray.Count();
while (i--) {
ProviderEntry* entry = NS_REINTERPRET_CAST(ProviderEntry*, mArray[i]);
delete entry;
}
mArray.Clear();
}
nsChromeRegistry::PackageEntry::PackageEntry(const nsACString& aPackage) :
package(aPackage), flags(0)
{
}
const void*
nsChromeRegistry::GetKey(PLDHashTable *table, PLDHashEntryHdr *entry)
{
PackageEntry* pentry = NS_STATIC_CAST(PackageEntry*, entry);
return (nsACString*) &pentry->package;
}
PLHashNumber
nsChromeRegistry::HashKey(PLDHashTable *table, const void *key)
{
const nsACString& str = *NS_REINTERPRET_CAST(const nsACString*, key);
return HashString(str);
}
PRBool
nsChromeRegistry::MatchKey(PLDHashTable *table, const PLDHashEntryHdr *entry,
const void *key)
{
const nsACString& str = *NS_REINTERPRET_CAST(const nsACString*, key);
const PackageEntry* pentry = NS_STATIC_CAST(const PackageEntry*, entry);
return str.Equals(pentry->package);
}
void
nsChromeRegistry::ClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
{
PackageEntry* pentry = NS_STATIC_CAST(PackageEntry*, entry);
pentry->~PackageEntry();
}
PRBool
nsChromeRegistry::InitEntry(PLDHashTable *table, PLDHashEntryHdr *entry,
const void *key)
{
const nsACString& str = *NS_REINTERPRET_CAST(const nsACString*, key);
new (entry) PackageEntry(str);
return PR_TRUE;
}
const PLDHashTableOps
nsChromeRegistry::kTableOps = {
PL_DHashAllocTable,
PL_DHashFreeTable,
GetKey,
HashKey,
MatchKey,
PL_DHashMoveEntryStub,
ClearEntry,
PL_DHashFinalizeStub,
InitEntry
};
void
nsChromeRegistry::OverlayListEntry::AddURI(nsIURI* aURI)
{
PRInt32 i = mArray.Count();
while (i--) {
PRBool equals;
if (NS_SUCCEEDED(aURI->Equals(mArray[i], &equals)) && equals)
return;
}
mArray.AppendObject(aURI);
}
void
nsChromeRegistry::OverlayListHash::Add(nsIURI* aBase, nsIURI* aOverlay)
{
OverlayListEntry* entry = mTable.PutEntry(aBase);
if (entry)
entry->AddURI(aOverlay);
}
const nsCOMArray<nsIURI>*
nsChromeRegistry::OverlayListHash::GetArray(nsIURI* aBase)
{
OverlayListEntry* entry = mTable.GetEntry(aBase);
if (!entry)
return nsnull;
return &entry->mArray;
}
nsChromeRegistry::~nsChromeRegistry()
{
gChromeRegistry = nsnull;
1999-04-02 00:52:35 +00:00
}
NS_IMPL_THREADSAFE_ISUPPORTS6(nsChromeRegistry,
nsIChromeRegistry,
nsIXULChromeRegistry,
nsIToolkitChromeRegistry,
nsIXULOverlayProvider,
nsIObserver,
nsISupportsWeakReference)
1999-04-02 00:52:35 +00:00
////////////////////////////////////////////////////////////////////////////////
// nsIChromeRegistry methods:
static nsresult
getUILangCountry(nsACString& aUILang)
{
nsresult rv;
nsCOMPtr<nsILocaleService> localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString uiLang;
rv = localeService->GetLocaleComponentForUserAgent(uiLang);
NS_ENSURE_SUCCESS(rv, rv);
CopyUTF16toUTF8(uiLang, aUILang);
return NS_OK;
}
nsresult
nsChromeRegistry::Init()
{
nsresult rv;
// these atoms appear in almost every chrome registry contents.rdf
// in some form or another. making static atoms prevents the atoms
// from constantly being created/destroyed during parsing
static const nsStaticAtom atoms[] = {
{ "chrome", nsnull },
{ "NC", nsnull },
{ "allowScripts", nsnull },
{ "package", nsnull },
{ "packages", nsnull },
{ "hasOverlays", nsnull },
};
NS_RegisterStaticAtoms(atoms, NS_ARRAY_LENGTH(atoms));
if (!PL_DHashTableInit(&mPackagesHash, &kTableOps,
nsnull, sizeof(PackageEntry), 16))
return NS_ERROR_FAILURE;
if (!mOverlayHash.Init() ||
!mStyleHash.Init())
return NS_ERROR_FAILURE;
gChromeRegistry = this;
mSelectedLocale = NS_LITERAL_CSTRING("en-US");
mSelectedSkin = NS_LITERAL_CSTRING("classic/1.0");
nsCOMPtr<nsIPrefBranchInternal> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
if (!prefs) {
NS_WARNING("Could not get pref service!");
}
PRBool useLocalePref = PR_TRUE;
if (prefs) {
// check the pref first
PRBool matchOS = PR_FALSE;
rv = prefs->GetBoolPref(MATCH_OS_LOCALE_PREF, &matchOS);
// match os locale
if (NS_SUCCEEDED(rv) && matchOS) {
// compute lang and region code only when needed!
nsCAutoString uiLocale;
rv = getUILangCountry(uiLocale);
if (NS_SUCCEEDED(rv)) {
useLocalePref = PR_FALSE;
mSelectedLocale = uiLocale;
}
}
}
if (prefs) {
nsXPIDLCString provider;
rv = prefs->GetCharPref(SELECTED_SKIN_PREF, getter_Copies(provider));
if (NS_SUCCEEDED(rv))
mSelectedSkin = provider;
rv = prefs->AddObserver(SELECTED_SKIN_PREF, this, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't add skin-switching observer!");
if (useLocalePref) {
rv = prefs->GetCharPref(SELECTED_LOCALE_PREF, getter_Copies(provider));
if (NS_SUCCEEDED(rv))
mSelectedLocale = provider;
prefs->AddObserver(SELECTED_LOCALE_PREF, this, PR_TRUE);
}
}
CheckForNewChrome();
return NS_OK;
}
NS_IMETHODIMP
nsChromeRegistry::CheckForOSAccessibility()
{
nsresult rv;
nsCOMPtr<nsILookAndFeel> lookAndFeel (do_GetService(kLookAndFeelCID));
if (lookAndFeel) {
PRInt32 useAccessibilityTheme = 0;
rv = lookAndFeel->GetMetric(nsILookAndFeel::eMetric_UseAccessibilityTheme,
useAccessibilityTheme);
if (NS_SUCCEEDED(rv) && useAccessibilityTheme) {
/* Set the skin to classic and remove pref observers */
if (!mSelectedSkin.EqualsLiteral("classic/1.0")) {
mSelectedSkin.AssignLiteral("classic/1.0");
RefreshSkins();
}
nsCOMPtr<nsIPrefBranchInternal> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
if (prefs) {
prefs->RemoveObserver(SELECTED_SKIN_PREF, this);
}
}
}
return NS_OK;
}
nsresult
nsChromeRegistry::GetProviderAndPath(nsIURL* aChromeURL,
nsACString& aProvider, nsACString& aPath)
{
nsresult rv;
#ifdef DEBUG
PRBool isChrome;
aChromeURL->SchemeIs("chrome", &isChrome);
NS_ASSERTION(isChrome, "Non-chrome URI?");
#endif
1999-04-02 00:52:35 +00:00
nsCAutoString path;
rv = aChromeURL->GetPath(path);
NS_ENSURE_SUCCESS(rv, rv);
if (path.Length() < 3)
return NS_ERROR_FAILURE;
path.SetLength(nsUnescapeCount(path.BeginWriting()));
NS_ASSERTION(path.First() == '/', "Path should always begin with a slash!");
PRInt32 slash = path.FindChar('/', 1);
if (slash == 1)
return NS_ERROR_FAILURE;
if (slash == -1) {
aPath.Truncate();
}
else {
if (slash == (PRInt32) path.Length() - 1)
aPath.Truncate();
else
aPath.Assign(path.get() + slash + 1, path.Length() - slash - 1);
--slash;
}
aProvider.Assign(path.get() + 1, slash);
return NS_OK;
}
static NS_NAMED_LITERAL_CSTRING(kSlash, "/");
nsresult
nsChromeRegistry::Canonify(nsIURL* aChromeURL)
{
nsresult rv;
nsCAutoString provider, path;
rv = GetProviderAndPath(aChromeURL, provider, path);
NS_ENSURE_SUCCESS(rv, rv);
if (path.IsEmpty()) {
nsCAutoString package;
rv = aChromeURL->GetHost(package);
NS_ENSURE_SUCCESS(rv, rv);
// we re-use the "path" local string to build a new URL path
path.Assign(kSlash + provider + kSlash + package);
if (provider.EqualsLiteral("content")) {
path.AppendLiteral(".xul");
}
else if (provider.EqualsLiteral("locale")) {
path.AppendLiteral(".dtd");
}
else if (provider.EqualsLiteral("skin")) {
path.AppendLiteral(".css");
}
else {
// XXXbsmedberg: report this to the console service?
return NS_ERROR_INVALID_ARG;
}
aChromeURL->SetPath(path);
}
else if (path.Find(NS_LITERAL_CSTRING("..")) != -1) {
return NS_ERROR_DOM_BAD_URI;
}
return NS_OK;
}
NS_IMETHODIMP
nsChromeRegistry::ConvertChromeURL(nsIURI* aChromeURI, nsIURI* *aResult)
2000-05-13 21:42:56 +00:00
{
nsresult rv;
NS_ASSERTION(aChromeURI, "null url!");
nsCOMPtr<nsIURL> chromeURL (do_QueryInterface(aChromeURI));
NS_ENSURE_TRUE(chromeURL, NS_NOINTERFACE);
nsCAutoString package, provider, path;
rv = chromeURL->GetHostPort(package);
NS_ENSURE_SUCCESS(rv, rv);
rv = GetProviderAndPath(chromeURL, provider, path);
NS_ENSURE_SUCCESS(rv, rv);
PackageEntry* entry =
NS_STATIC_CAST(PackageEntry*, PL_DHashTableOperate(&mPackagesHash,
& (nsACString&) package,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_FREE(entry))
return NS_ERROR_FAILURE;
if (entry->flags & PackageEntry::PLATFORM_PACKAGE) {
#if defined(XP_WIN) || defined(XP_OS2)
path.Insert("win/", 0);
#elif defined(XP_MACOSX)
path.Insert("mac/", 0);
#else
path.Insert("unix/", 0);
#endif
}
nsIURI* baseURI = nsnull;
if (provider.EqualsLiteral("locale")) {
baseURI = entry->locales.GetBase(mSelectedLocale, nsProviderArray::LOCALE);
}
else if (provider.EqualsLiteral("skin")) {
baseURI = entry->skins.GetBase(mSelectedSkin, nsProviderArray::SKIN);
}
else {
baseURI = entry->baseURI;
}
if (!baseURI)
return NS_ERROR_FAILURE;
return NS_NewURI(aResult, path, nsnull, baseURI);
2000-05-13 21:42:56 +00:00
}
nsresult
nsChromeRegistry::GetSelectedLocale(const nsACString& aPackage, nsACString& aLocale)
{
PackageEntry* entry =
NS_STATIC_CAST(PackageEntry*, PL_DHashTableOperate(&mPackagesHash,
& aPackage,
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_FREE(entry))
return NS_ERROR_FAILURE;
aLocale = entry->locales.GetSelected(mSelectedLocale, nsProviderArray::LOCALE);
if (aLocale.IsEmpty())
return NS_ERROR_FAILURE;
return NS_OK;
}
NS_IMETHODIMP
nsChromeRegistry::GetStyleOverlays(nsIURI *aChromeURL,
nsISimpleEnumerator **aResult)
{
const nsCOMArray<nsIURI>* parray = mStyleHash.GetArray(aChromeURL);
if (!parray)
return NS_NewEmptyEnumerator(aResult);
return NS_NewArrayEnumerator(aResult, *parray);
}
NS_IMETHODIMP
nsChromeRegistry::GetXULOverlays(nsIURI *aChromeURL, nsISimpleEnumerator **aResult)
{
const nsCOMArray<nsIURI>* parray = mOverlayHash.GetArray(aChromeURL);
if (!parray)
return NS_NewEmptyEnumerator(aResult);
return NS_NewArrayEnumerator(aResult, *parray);
}
////////////////////////////////////////////////////////////////////////
1999-10-27 09:24:23 +00:00
// theme stuff
static void FlushSkinBindingsForWindow(nsIDOMWindowInternal* aWindow)
{
// Get the DOM document.
nsCOMPtr<nsIDOMDocument> domDocument;
aWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return;
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
if (!document)
return;
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
// Annihilate all XBL bindings.
document->BindingManager()->FlushSkinBindings();
}
// XXXbsmedberg: move this to nsIWindowMediator
NS_IMETHODIMP nsChromeRegistry::RefreshSkins()
{
nsCOMPtr<nsIWindowMediator> windowMediator
(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
if (!windowMediator)
return NS_OK;
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
PRBool more;
windowEnumerator->HasMoreElements(&more);
while (more) {
nsCOMPtr<nsISupports> protoWindow;
windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (protoWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(protoWindow);
if (domWindow)
FlushSkinBindingsForWindow(domWindow);
}
windowEnumerator->HasMoreElements(&more);
}
FlushSkinCaches();
windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
windowEnumerator->HasMoreElements(&more);
while (more) {
nsCOMPtr<nsISupports> protoWindow;
windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (protoWindow) {
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(protoWindow);
if (domWindow)
RefreshWindow(domWindow);
}
windowEnumerator->HasMoreElements(&more);
}
return NS_OK;
}
void
nsChromeRegistry::FlushSkinCaches()
{
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService("@mozilla.org/observer-service;1");
NS_ASSERTION(obsSvc, "Couldn't get observer service.");
2000-05-27 20:03:14 +00:00
obsSvc->NotifyObservers(NS_STATIC_CAST(nsIChromeRegistry*, this),
NS_CHROME_FLUSH_SKINS_TOPIC, nsnull);
}
static PRBool IsChromeURI(nsIURI* aURI)
{
PRBool isChrome=PR_FALSE;
if (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) && isChrome)
return PR_TRUE;
return PR_FALSE;
}
// XXXbsmedberg: move this to windowmediator
nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
1999-10-27 09:24:23 +00:00
{
// Deal with our subframes first.
nsCOMPtr<nsIDOMWindowCollection> frames;
aWindow->GetFrames(getter_AddRefs(frames));
PRUint32 length;
frames->GetLength(&length);
PRUint32 j;
for (j = 0; j < length; j++) {
nsCOMPtr<nsIDOMWindow> childWin;
frames->Item(j, getter_AddRefs(childWin));
nsCOMPtr<nsIDOMWindowInternal> childInt(do_QueryInterface(childWin));
RefreshWindow(childInt);
}
nsresult rv;
// Get the DOM document.
nsCOMPtr<nsIDOMDocument> domDocument;
aWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return NS_OK;
nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument);
if (!document)
return NS_OK;
// Deal with the agent sheets first. Have to do all the style sets by hand.
PRUint32 shellCount = document->GetNumberOfShells();
for (PRUint32 k = 0; k < shellCount; k++) {
nsIPresShell *shell = document->GetShellAt(k);
// Reload only the chrome URL agent style sheets.
nsCOMArray<nsIStyleSheet> agentSheets;
rv = shell->GetAgentStyleSheets(agentSheets);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMArray<nsIStyleSheet> newAgentSheets;
for (PRInt32 l = 0; l < agentSheets.Count(); ++l) {
nsIStyleSheet *sheet = agentSheets[l];
nsCOMPtr<nsIURI> uri;
rv = sheet->GetSheetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (IsChromeURI(uri)) {
// Reload the sheet.
nsCOMPtr<nsICSSStyleSheet> newSheet;
rv = LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
if (NS_FAILED(rv)) return rv;
if (newSheet) {
rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
}
2000-05-27 20:03:14 +00:00
}
else { // Just use the same sheet.
rv = newAgentSheets.AppendObject(sheet) ? NS_OK : NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
}
2000-05-27 20:03:14 +00:00
}
rv = shell->SetAgentStyleSheets(newAgentSheets);
NS_ENSURE_SUCCESS(rv, rv);
}
2000-05-27 20:03:14 +00:00
// Build an array of nsIURIs of style sheets we need to load.
nsCOMArray<nsIStyleSheet> oldSheets;
nsCOMArray<nsIStyleSheet> newSheets;
2000-05-27 20:03:14 +00:00
PRInt32 count = document->GetNumberOfStyleSheets();
2000-05-27 20:03:14 +00:00
// Iterate over the style sheets.
PRInt32 i;
for (i = 0; i < count; i++) {
// Get the style sheet
nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i);
if (!oldSheets.AppendObject(styleSheet)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
// Iterate over our old sheets and kick off a sync load of the new
// sheet if and only if it's a chrome URL.
for (i = 0; i < count; i++) {
nsCOMPtr<nsIStyleSheet> sheet = oldSheets[i];
nsCOMPtr<nsIURI> uri;
rv = sheet->GetSheetURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) return rv;
if (IsChromeURI(uri)) {
// Reload the sheet.
#ifdef DEBUG
nsCOMPtr<nsICSSStyleSheet> oldCSSSheet = do_QueryInterface(sheet);
NS_ASSERTION(oldCSSSheet, "Don't know how to reload a non-CSS sheet");
#endif
nsCOMPtr<nsICSSStyleSheet> newSheet;
// XXX what about chrome sheets that have a title or are disabled? This
// only works by sheer dumb luck.
// XXXbz this should really use the document's CSSLoader!
LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
// Even if it's null, we put in in there.
newSheets.AppendObject(newSheet);
}
else {
// Just use the same sheet.
newSheets.AppendObject(sheet);
}
}
// Now notify the document that multiple sheets have been added and removed.
document->UpdateStyleSheets(oldSheets, newSheets);
1999-10-27 09:24:23 +00:00
return NS_OK;
}
void
nsChromeRegistry::FlushAllCaches()
1999-10-27 09:24:23 +00:00
{
nsCOMPtr<nsIObserverService> obsSvc =
do_GetService("@mozilla.org/observer-service;1");
NS_ASSERTION(obsSvc, "Couldn't get observer service.");
obsSvc->NotifyObservers((nsIChromeRegistry*) this,
NS_CHROME_FLUSH_TOPIC, nsnull);
}
// xxxbsmedberg Move me to nsIWindowMediator
NS_IMETHODIMP
nsChromeRegistry::ReloadChrome()
{
FlushAllCaches();
// Do a reload of all top level windows.
nsresult rv = NS_OK;
// Get the window mediator
nsCOMPtr<nsIWindowMediator> windowMediator
(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
if (windowMediator) {
nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
rv = windowMediator->GetEnumerator(nsnull, getter_AddRefs(windowEnumerator));
if (NS_SUCCEEDED(rv)) {
// Get each dom window
PRBool more;
rv = windowEnumerator->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
while (more) {
nsCOMPtr<nsISupports> protoWindow;
rv = windowEnumerator->GetNext(getter_AddRefs(protoWindow));
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIDOMWindowInternal> domWindow =
do_QueryInterface(protoWindow);
if (domWindow) {
nsCOMPtr<nsIDOMLocation> location;
domWindow->GetLocation(getter_AddRefs(location));
if (location) {
rv = location->Reload(PR_FALSE);
if (NS_FAILED(rv)) return rv;
}
}
}
rv = windowEnumerator->HasMoreElements(&more);
if (NS_FAILED(rv)) return rv;
}
}
}
return rv;
}
nsresult
nsChromeRegistry::LoadStyleSheetWithURL(nsIURI* aURL, nsICSSStyleSheet** aSheet)
{
*aSheet = nsnull;
nsCOMPtr<nsICSSLoader> cssLoader = do_GetService(kCSSLoaderCID);
if (!cssLoader) return NS_ERROR_FAILURE;
return cssLoader->LoadAgentSheet(aURL, aSheet);
}
NS_IMETHODIMP
nsChromeRegistry::AllowScriptsForPackage(nsIURI* aChromeURI, PRBool *aResult)
{
nsresult rv;
*aResult = PR_FALSE;
#ifdef DEBUG
PRBool isChrome;
aChromeURI->SchemeIs("chrome", &isChrome);
NS_ASSERTION(isChrome, "Non-chrome URI passed to AllowScriptsForPackage!");
#endif
nsCOMPtr<nsIURL> url (do_QueryInterface(aChromeURI));
NS_ENSURE_TRUE(url, NS_NOINTERFACE);
nsCAutoString provider, file;
rv = GetProviderAndPath(url, provider, file);
NS_ENSURE_SUCCESS(rv, rv);
if (!provider.EqualsLiteral("skin"))
*aResult = PR_TRUE;
return NS_OK;
}
static PLDHashOperator
RemoveAll(PLDHashTable *table, PLDHashEntryHdr *entry, PRUint32 number, void *arg)
{
return (PLDHashOperator) (PL_DHASH_NEXT | PL_DHASH_REMOVE);
}
NS_IMETHODIMP
nsChromeRegistry::CheckForNewChrome()
{
nsresult rv;
2000-03-22 01:30:04 +00:00
PL_DHashTableEnumerate(&mPackagesHash, RemoveAll, nsnull);
mOverlayHash.Clear();
mStyleHash.Clear();
nsCOMPtr<nsIURI> manifestURI;
rv = NS_NewURI(getter_AddRefs(manifestURI),
NS_LITERAL_CSTRING("resource:///chrome/app-chrome.manifest"));
// this is the main manifest; if it doesn't exist we generate it from
// installed-chrome.txt. When the build system learns about the new system,
// this code can go away.
nsCOMPtr<nsIFileURL> manifestFileURL (do_QueryInterface(manifestURI));
NS_ASSERTION(manifestFileURL, "Not a nsIFileURL!");
2000-03-22 01:30:04 +00:00
nsCOMPtr<nsIFile> manifest;
manifestFileURL->GetFile(getter_AddRefs(manifest));
NS_ENSURE_TRUE(manifest, NS_ERROR_FAILURE);
PRBool exists;
rv = manifest->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
2000-03-22 01:30:04 +00:00
#ifdef DEBUG
// In debug builds, installed-chrome.txt may change during development;
// we just rebuild it every time because we're not worried about startup
// time or other bad/goodness.
if (exists) {
manifest->Remove(PR_FALSE);
exists = PR_FALSE;
}
#endif
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
if (!exists) {
nsCOMPtr<nsIFile> installed;
manifest->Clone(getter_AddRefs(installed));
if (!installed)
return NS_ERROR_OUT_OF_MEMORY;
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
nsCOMPtr<nsILocalFile> linstalled (do_QueryInterface(installed));
NS_ENSURE_TRUE(linstalled, NS_NOINTERFACE);
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
linstalled->SetNativeLeafName(NS_LITERAL_CSTRING("installed-chrome.txt"));
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
// process installed-chrome.txt into app-chrome.manifest
ProcessNewChromeFile(linstalled, manifestURI);
}
2000-03-22 01:30:04 +00:00
nsCOMPtr<nsIProperties> dirSvc (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
NS_ENSURE_TRUE(dirSvc, NS_ERROR_FAILURE);
// check the extra chrome directories
nsCOMPtr<nsISimpleEnumerator> chromeML;
rv = dirSvc->Get(NS_CHROME_MANIFESTS_FILE_LIST, NS_GET_IID(nsISimpleEnumerator),
getter_AddRefs(chromeML));
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsISupports> next;
while (NS_SUCCEEDED(chromeML->HasMoreElements(&exists)) && exists) {
chromeML->GetNext(getter_AddRefs(next));
nsCOMPtr<nsILocalFile> lmanifest = do_QueryInterface(next);
if (!lmanifest) {
NS_ERROR("Directory enumerator returned a non-nsILocalFile");
continue;
}
PRBool isDir;
if (NS_SUCCEEDED(lmanifest->IsDirectory(&isDir)) && isDir) {
nsCOMPtr<nsISimpleEnumerator> entries;
rv = lmanifest->GetDirectoryEntries(getter_AddRefs(entries));
if (NS_FAILED(rv)) {
NS_WARNING("Could not process chrome manifest directory.");
continue;
}
while (NS_SUCCEEDED(entries->HasMoreElements(&exists)) && exists) {
entries->GetNext(getter_AddRefs(next));
lmanifest = do_QueryInterface(next);
if (lmanifest) {
nsCAutoString leafName;
lmanifest->GetNativeLeafName(leafName);
if (StringEndsWith(leafName, NS_LITERAL_CSTRING(".manifest"))) {
rv = ProcessManifest(lmanifest, PR_FALSE);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to process manifest.");
}
}
}
2000-03-22 01:30:04 +00:00
}
}
else {
rv = ProcessManifest(lmanifest, PR_FALSE);
#ifdef DEBUG
if (NS_FAILED(rv)) {
nsCString path;
lmanifest->GetNativePath(path);
path.Insert(NS_LITERAL_CSTRING("Failed to process chrome manifest: "), 0);
NS_WARNING(path.get());
2000-03-22 01:30:04 +00:00
}
#endif
2000-03-22 01:30:04 +00:00
}
}
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
rv = dirSvc->Get(NS_SKIN_MANIFESTS_FILE_LIST, NS_GET_IID(nsISimpleEnumerator),
getter_AddRefs(chromeML));
2000-03-22 01:30:04 +00:00
if (NS_FAILED(rv))
return NS_OK;
while (NS_SUCCEEDED(chromeML->HasMoreElements(&exists)) && exists) {
chromeML->GetNext(getter_AddRefs(next));
nsCOMPtr<nsILocalFile> lmanifest = do_QueryInterface(next);
if (!lmanifest) {
NS_ERROR("Directory enumerator returned a non-nsILocalFile");
continue;
}
2000-03-22 01:30:04 +00:00
rv = ProcessManifest(lmanifest, PR_TRUE);
#ifdef DEBUG
if (NS_FAILED(rv)) {
nsCString path;
lmanifest->GetNativePath(path);
path.Insert(NS_LITERAL_CSTRING("Failed to process skin manifest: "), 0);
NS_WARNING(path.get());
}
#endif
}
2000-03-22 01:30:04 +00:00
return NS_OK;
}
nsresult
nsChromeRegistry::ProcessNewChromeFile(nsILocalFile *aListFile, nsIURI* aManifest)
{
nsresult rv;
PRFileDesc *file;
rv = aListFile->OpenNSPRFileDesc(PR_RDONLY, 0, &file);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 n, size;
char *buf;
size = PR_Available(file);
if (size == -1) {
rv = NS_ERROR_UNEXPECTED;
goto end;
}
2000-03-22 01:30:04 +00:00
buf = (char *) malloc(size + 1);
if (!buf) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto end;
}
n = PR_Read(file, buf, size);
if (n > 0)
rv = ProcessNewChromeBuffer(buf, size, aManifest);
free(buf);
2001-03-06 01:42:34 +00:00
end:
PR_Close(file);
return rv;
}
nsresult
nsChromeRegistry::ProcessNewChromeBuffer(char *aBuffer, PRInt32 aLength,
nsIURI* aManifest)
{
nsresult rv = NS_OK;
char *bufferEnd = aBuffer + aLength;
char *chromeType, // "content", "locale" or "skin"
*chromeProfile, // "install" or "profile"
*chromeLocType, // type of location (local path or URL)
*chromeLocation; // base location of chrome (jar file)
2001-03-06 01:42:34 +00:00
nsCOMPtr<nsIURI> baseURI;
// process chromeType, chromeProfile, chromeLocType, chromeLocation
while (aBuffer < bufferEnd) {
// parse one line of installed-chrome.txt
chromeType = aBuffer;
while (aBuffer < bufferEnd && *aBuffer != ',')
++aBuffer;
*aBuffer = '\0';
chromeProfile = ++aBuffer;
if (aBuffer >= bufferEnd)
break;
while (aBuffer < bufferEnd && *aBuffer != ',')
++aBuffer;
*aBuffer = '\0';
chromeLocType = ++aBuffer;
if (aBuffer >= bufferEnd)
break;
while (aBuffer < bufferEnd && *aBuffer != ',')
++aBuffer;
*aBuffer = '\0';
chromeLocation = ++aBuffer;
if (aBuffer >= bufferEnd)
break;
while (aBuffer < bufferEnd &&
(*aBuffer != '\r' && *aBuffer != '\n' && *aBuffer != ' '))
++aBuffer;
*aBuffer = '\0';
// process the line
// We don't do skin or locale selection from installed-chrome.txt since
// ffox 0.9. Just ignore the "select" lines.
if (strcmp(chromeLocType,"select")) {
if (!strcmp(chromeLocType, "path")) {
// location is a (full) path. convert it to an URL.
/* this is some convoluted shit... this creates a file, inits it with
* the path parsed above (chromeLocation), makes a url, and inits it
* with the file created. the purpose of this is just to have the
* canonical url of the stupid thing.
*/
nsCOMPtr<nsILocalFile> chromeFile;
rv = NS_NewNativeLocalFile(nsDependentCString(chromeLocation),
PR_TRUE, getter_AddRefs(chromeFile));
NS_ENSURE_SUCCESS(rv, rv);
/*
* all we want here is the canonical url
*/
rv = NS_NewFileURI(getter_AddRefs(baseURI), chromeFile);
if (NS_FAILED(rv)) return rv;
}
else {
rv = NS_NewURI(getter_AddRefs(baseURI), chromeLocation);
if (NS_FAILED(rv)) return rv;
}
ProcessContentsManifest(baseURI, aManifest, PR_TRUE, strcmp(chromeType, "skin") == 0);
}
while (aBuffer < bufferEnd && (*aBuffer == '\0' || *aBuffer == ' ' || *aBuffer == '\r' || *aBuffer == '\n'))
++aBuffer;
}
return NS_OK;
2001-03-06 01:42:34 +00:00
}
NS_IMETHODIMP nsChromeRegistry::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
{
nsresult rv = NS_OK;
if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
nsCOMPtr<nsIPrefBranch> prefs (do_QueryInterface(aSubject));
NS_ASSERTION(prefs, "Bad observer call!");
NS_ConvertUTF16toUTF8 pref(someData);
nsXPIDLCString provider;
rv = prefs->GetCharPref(pref.get(), getter_Copies(provider));
if (NS_FAILED(rv)) {
NS_ERROR("Couldn't get new locale or skin pref!");
return rv;
}
if (pref.EqualsLiteral(SELECTED_SKIN_PREF)) {
mSelectedSkin = provider;
RefreshSkins();
}
else if (pref.EqualsLiteral(SELECTED_LOCALE_PREF)) {
mSelectedLocale = provider;
FlushAllCaches();
} else {
NS_ERROR("Unexpected pref!");
}
}
else if (!strcmp("command-line-startup", aTopic)) {
nsCOMPtr<nsICommandLine> cmdLine (do_QueryInterface(aSubject));
if (cmdLine) {
nsAutoString uiLocale;
rv = cmdLine->HandleFlagWithParam(NS_LITERAL_STRING(UILOCALE_CMD_LINE_ARG),
PR_FALSE, uiLocale);
if (NS_SUCCEEDED(rv) && !uiLocale.IsEmpty()) {
CopyUTF16toUTF8(uiLocale, mSelectedLocale);
nsCOMPtr<nsIPrefBranchInternal> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
if (prefs) {
prefs->RemoveObserver(SELECTED_LOCALE_PREF, this);
}
}
}
}
else {
NS_ERROR("Unexpected observer topic!");
}
return rv;
}
static nsresult
GetContainerEnumerator(nsIRDFDataSource* ds, nsIRDFResource* res,
nsISimpleEnumerator* *aResult, PRInt32 *aCountResult = nsnull)
{
nsresult rv;
nsCOMPtr<nsIRDFContainer> container
(do_CreateInstance("@mozilla.org/rdf/container;1"));
NS_ENSURE_TRUE(container, NS_ERROR_FAILURE);
rv = container->Init(ds, res);
if (NS_FAILED(rv)) return rv;
if (aCountResult)
container->GetCount(aCountResult);
return container->GetElements(aResult);
}
static void
FollowLiteral(nsIRDFDataSource* ds, nsIRDFResource* res,
nsIRDFResource* arc, nsACString& result)
{
nsresult rv;
nsCOMPtr<nsIRDFNode> node;
rv = ds->GetTarget(res, arc, PR_TRUE, getter_AddRefs(node));
if (NS_FAILED(rv) || !node) {
result.Truncate();
return;
}
nsCOMPtr<nsIRDFLiteral> literal (do_QueryInterface(node));
if (!literal) {
NS_ERROR("Arc found, but doesn't point to expected literal!");
result.Truncate();
return;
}
const PRUnichar* value;
literal->GetValueConst(&value);
CopyUTF16toUTF8(value, result);
}
static void
FollowResource(nsIRDFDataSource* ds, nsIRDFResource* res, nsIRDFResource* arc,
nsIRDFResource* *result)
{
nsresult rv;
nsCOMPtr<nsIRDFNode> node;
rv = ds->GetTarget(res, arc, PR_TRUE, getter_AddRefs(node));
if (NS_FAILED(rv) || !node) {
*result = nsnull;
return;
}
CallQueryInterface(node, result);
}
static void
GetRelativePath(nsIURI* base, nsIURI* relative, nsACString& result)
2001-03-06 01:42:34 +00:00
{
nsresult rv;
2001-03-06 01:42:34 +00:00
nsCOMPtr<nsIJARURI> jarrelative (do_QueryInterface(relative));
if (jarrelative) {
nsCOMPtr<nsIURI> jarbase;
jarrelative->GetJARFile(getter_AddRefs(jarbase));
2001-03-06 01:42:34 +00:00
nsCAutoString relativeBase;
GetRelativePath(base, jarbase, relativeBase);
2001-03-06 01:42:34 +00:00
nsCAutoString jarEntry;
jarrelative->GetJAREntry(jarEntry);
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
result.Assign(NS_LITERAL_CSTRING("jar:"));
result.Append(relativeBase);
result.Append(NS_LITERAL_CSTRING("!/"));
result.Append(jarEntry);
return;
}
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
nsCOMPtr<nsIURL> baseURL (do_QueryInterface(base));
if (!baseURL) {
relative->GetSpec(result);
return;
}
2001-03-06 01:42:34 +00:00
rv = baseURL->GetRelativeSpec(relative, result);
if (NS_FAILED(rv)) {
relative->GetSpec(result);
}
}
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
static const PRInt32 kNSPR_APPEND_FLAGS = PR_WRONLY | PR_CREATE_FILE | PR_APPEND;
static const PRInt32 kNSPR_TRUNCATE_FLAGS = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
NS_IMETHODIMP
nsChromeRegistry::ProcessContentsManifest(nsIURI* aOldManifest, nsIURI* aFile,
PRBool aAppend, PRBool aSkinOnly)
{
nsresult rv;
nsCAutoString relativePath;
GetRelativePath(aFile, aOldManifest, relativePath);
1999-10-27 09:24:23 +00:00
nsCAutoString spec;
aOldManifest->GetSpec(spec);
NS_ASSERTION(spec.Last() == '/', "installed-chrome manifest URI doesn't end in a slash! It probably won't work.");
spec.AppendLiteral("contents.rdf");
nsCOMPtr<nsIRDFService> rdfs (do_GetService("@mozilla.org/rdf/rdf-service;1"));
NS_ENSURE_TRUE(rdfs, NS_ERROR_FAILURE);
1999-11-30 09:29:43 +00:00
nsCOMPtr<nsIRDFResource> namearc, platformarc;
rdfs->GetResource(NS_LITERAL_CSTRING(kURICHROME_name),
getter_AddRefs(namearc));
rdfs->GetResource(NS_LITERAL_CSTRING(kURICHROME_platformPackage),
getter_AddRefs(platformarc));
if (!(namearc && platformarc))
return NS_ERROR_FAILURE;
nsCOMPtr<nsIRDFDataSource> ds;
rv = rdfs->GetDataSourceBlocking(spec.get(), getter_AddRefs(ds));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIFileURL> fileURL (do_QueryInterface(aFile));
NS_ENSURE_TRUE(fileURL, NS_ERROR_INVALID_ARG);
1999-11-30 09:29:43 +00:00
nsCOMPtr<nsIFile> file;
rv = fileURL->GetFile(getter_AddRefs(file));
NS_ENSURE_SUCCESS(rv, rv);
1999-11-30 09:29:43 +00:00
nsCOMPtr<nsILocalFile> lfile (do_QueryInterface(file));
NS_ENSURE_TRUE(lfile, NS_ERROR_NO_INTERFACE);
PRFileDesc* fd;
rv = lfile->OpenNSPRFileDesc(aAppend ? kNSPR_APPEND_FLAGS : kNSPR_TRUNCATE_FLAGS,
0664, &fd);
NS_ENSURE_SUCCESS(rv, rv);
if (aAppend)
PR_Write(fd, "\n", 1);
nsCOMPtr<nsIRDFResource> root;
rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:skin:root"),
getter_AddRefs(root));
if (NS_SUCCEEDED(rv))
ProcessProvider(fd, rdfs, ds, root, PR_FALSE, relativePath);
rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:stylesheets"),
getter_AddRefs(root));
if (NS_SUCCEEDED(rv))
ProcessOverlays(fd, ds, root, NS_LITERAL_CSTRING("style"));
if (!aSkinOnly) {
rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:locale:root"),
getter_AddRefs(root));
if (NS_SUCCEEDED(rv))
ProcessProvider(fd, rdfs, ds, root, PR_TRUE, relativePath);
rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:overlays"),
getter_AddRefs(root));
if (NS_SUCCEEDED(rv))
ProcessOverlays(fd, ds, root, NS_LITERAL_CSTRING("overlay"));
/* content packages are easier, but different */
rv = rdfs->GetResource(NS_LITERAL_CSTRING("urn:mozilla:package:root"),
getter_AddRefs(root));
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
nsCOMPtr<nsISimpleEnumerator> packages;
if (NS_SUCCEEDED(rv))
rv = GetContainerEnumerator(ds, root, getter_AddRefs(packages));
if (NS_SUCCEEDED(rv)) {
PRBool more;
nsCOMPtr<nsISupports> next;
nsCOMPtr<nsIRDFResource> package;
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
while (NS_SUCCEEDED(packages->HasMoreElements(&more)) && more) {
packages->GetNext(getter_AddRefs(next));
package = do_QueryInterface(next);
if (!package) {
NS_WARNING("Arc from urn:mozilla:package:root points to non-resource node.");
continue;
}
nsCAutoString name;
FollowLiteral(ds, package, namearc, name);
if (name.IsEmpty())
continue;
nsCAutoString isPlatform;
FollowLiteral(ds, package, platformarc, isPlatform);
name.Insert(NS_LITERAL_CSTRING("content\t"), 0);
name.Append('\t');
name.Append(relativePath);
if (!isPlatform.IsEmpty())
name.AppendLiteral("\tplatform");
name.AppendLiteral(NS_LINEBREAK);
PR_Write(fd, name.get(), name.Length());
}
}
}
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
PR_Close(fd);
return NS_OK;
}
static void
GetResourceName(nsIRDFResource* res, nsACString& result)
2000-05-27 20:03:14 +00:00
{
// we need to get the provider name. Instead of doing something sane,
// we munge the resource URI, looking from the right for colons.
nsCAutoString providerURI;
res->GetValueUTF8(providerURI);
PRInt32 found = providerURI.RFindChar(':');
if (found == kNotFound) {
result.Truncate();
return;
}
result.Assign(Substring(providerURI, found + 1));
}
static NS_NAMED_LITERAL_CSTRING(kTab, "\t");
void
nsChromeRegistry::ProcessProvider(PRFileDesc *fd, nsIRDFService* aRDFs,
nsIRDFDataSource* aDS, nsIRDFResource* aRoot,
PRBool aIsLocale, const nsACString& aBaseURL)
{
nsresult rv;
nsCOMPtr<nsIRDFResource> packagesarc;
aRDFs->GetResource(NS_LITERAL_CSTRING(kURICHROME_packages),
getter_AddRefs(packagesarc));
if (!packagesarc) return;
nsCOMPtr<nsISimpleEnumerator> providers;
rv = GetContainerEnumerator(aDS, aRoot, getter_AddRefs(providers));
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsISupports> next;
PRBool more;
while (NS_SUCCEEDED(providers->HasMoreElements(&more)) && more) {
providers->GetNext(getter_AddRefs(next));
NS_ASSERTION(next, "GetNext failed after HasMoreElements succeeded.");
nsCOMPtr<nsIRDFResource> provider (do_QueryInterface(next));
if (!provider) {
NS_WARNING("Provider isn't a nsIRDFResource.");
continue;
}
nsCAutoString providerName;
GetResourceName(provider, providerName);
if (providerName.IsEmpty()) {
NS_WARNING("Couldn't calculate resource name.");
continue;
}
nsCOMPtr<nsIRDFResource> packages;
FollowResource(aDS, provider, packagesarc, getter_AddRefs(packages));
if (!packages) {
NS_WARNING("No chrome:packages arc found!");
continue;
}
PRInt32 count;
nsCOMPtr<nsISimpleEnumerator> packageList;
rv = GetContainerEnumerator(aDS, packages, getter_AddRefs(packageList), &count);
if (NS_FAILED(rv)) {
NS_WARNING("chrome:packages was not a sequence.");
continue;
}
nsCOMPtr<nsISupports> nextPackage;
PRBool morePackages;
while (NS_SUCCEEDED(packageList->HasMoreElements(&morePackages)) &&
morePackages) {
packageList->GetNext(getter_AddRefs(nextPackage));
nsCOMPtr<nsIRDFResource> packageRes (do_QueryInterface(nextPackage));
if (!packageRes) {
NS_WARNING("chrome:packages Seq points to a non-resource!");
continue;
}
nsCAutoString packageName;
GetResourceName(packageRes, packageName);
if (packageName.IsEmpty()) {
NS_WARNING("couldn't extract a package name.");
continue;
}
nsCAutoString line;
if (aIsLocale)
line.AppendLiteral("locale\t");
else
line.AppendLiteral("skin\t");
line += packageName + kTab + providerName + kTab + aBaseURL;
if (count > 1) {
line += packageName + kSlash;
}
line.AppendLiteral(NS_LINEBREAK);
PR_Write(fd, line.get(), line.Length());
}
}
}
static void
GetLiteralText(nsIRDFLiteral* lit, nsACString& result)
{
const PRUnichar* value;
lit->GetValueConst(&value);
CopyUTF16toUTF8(value, result);
}
static NS_NAMED_LITERAL_CSTRING(kLinebreak, NS_LINEBREAK);
void
nsChromeRegistry::ProcessOverlays(PRFileDesc *fd, nsIRDFDataSource* aDS,
nsIRDFResource* aRoot,
const nsCSubstring& aType)
{
nsresult rv;
nsCOMPtr<nsISimpleEnumerator> overlaids;
rv = GetContainerEnumerator(aDS, aRoot, getter_AddRefs(overlaids));
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsISupports> next;
PRBool more;
while (NS_SUCCEEDED(overlaids->HasMoreElements(&more)) && more) {
overlaids->GetNext(getter_AddRefs(next));
NS_ASSERTION(next, "GetNext failed after HasMoreElements succeeded.");
nsCOMPtr<nsIRDFResource> overlaid (do_QueryInterface(next));
if (!overlaid) {
NS_WARNING("Overlay arc is not a nsIRDFResource.");
continue;
}
nsCAutoString overlaidName;
overlaid->GetValueUTF8(overlaidName);
nsCOMPtr<nsISimpleEnumerator> overlays;
rv = GetContainerEnumerator(aDS, overlaid, getter_AddRefs(overlays));
if (NS_FAILED(rv))
continue;
while (NS_SUCCEEDED(overlays->HasMoreElements(&more)) && more) {
overlays->GetNext(getter_AddRefs(next));
NS_ASSERTION(next, "GetNext failed after HasMoreElements succeeded.");
nsCOMPtr<nsIRDFLiteral> overlay (do_QueryInterface(next));
if (!overlay) {
NS_WARNING("Overlay was not an RDF literal.");
continue;
}
nsCAutoString overlayName;
GetLiteralText(overlay, overlayName);
overlayName.Insert(aType + kTab + overlaidName + kTab, 0);
overlayName.Append(kLinebreak);
PR_Write(fd, overlayName.get(), overlayName.Length());
}
}
}
nsresult
nsChromeRegistry::ProcessManifest(nsILocalFile* aManifest, PRBool aSkinOnly)
{
nsresult rv;
PRFileDesc* fd;
rv = aManifest->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
NS_ENSURE_SUCCESS(rv, rv);
2000-05-13 21:42:56 +00:00
PRInt32 n, size;
char *buf;
2000-05-13 21:42:56 +00:00
size = PR_Available(fd);
if (size == -1) {
rv = NS_ERROR_UNEXPECTED;
goto mend;
}
2000-05-13 21:42:56 +00:00
buf = (char *) malloc(size + 1);
if (!buf) {
rv = NS_ERROR_OUT_OF_MEMORY;
goto mend;
2000-05-13 21:42:56 +00:00
}
n = PR_Read(fd, buf, size);
if (n > 0) {
buf[size] = '\0';
rv = ProcessManifestBuffer(buf, size, aManifest, aSkinOnly);
}
free(buf);
mend:
PR_Close(fd);
return rv;
2000-05-13 21:42:56 +00:00
}
static const char kWhitespace[] = "\t ";
static const char kNewlines[] = "\r\n";
nsresult
nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
nsILocalFile* aManifest,
PRBool aSkinOnly)
{
nsresult rv;
2000-05-13 21:42:56 +00:00
nsCOMPtr<nsIIOService> io (do_GetIOService());
if (!io) return NS_ERROR_FAILURE;
nsCOMPtr<nsIURI> manifestURI;
rv = io->NewFileURI(aManifest, getter_AddRefs(manifestURI));
NS_ENSURE_SUCCESS(rv, rv);
char *token;
char *newline = buf;
// outer loop tokenizes by newline
while (nsnull != (token = nsCRT::strtok(newline, kNewlines, &newline))) {
char *whitespace = token;
token = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
if (!token) continue;
2000-05-13 21:42:56 +00:00
if (!strcmp(token, "content")) {
if (aSkinOnly) {
NS_WARNING("Skin manifest contained content registration. Ignoring.");
continue;
}
char *package = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
char *uri = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
if (!package || !uri) {
NS_WARNING("Malformed chrome manifest, content entry.");
continue;
}
PRBool platform = PR_FALSE;
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace))) {
if (!strcmp(token, "platform"))
platform = PR_TRUE;
}
nsCOMPtr<nsIURI> resolved;
rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
getter_AddRefs(resolved));
if (NS_FAILED(rv))
continue;
PackageEntry* entry =
NS_STATIC_CAST(PackageEntry*, PL_DHashTableOperate(&mPackagesHash,
& (const nsACString&) nsDependentCString(package),
PL_DHASH_ADD));
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
entry->baseURI = resolved;
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
if (platform)
entry->flags |= PackageEntry::PLATFORM_PACKAGE;
}
else if (!strcmp(token, "locale")) {
if (aSkinOnly) {
NS_WARNING("Skin manifest contained locale registration. Ignoring.");
continue;
}
char *package = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
char *provider = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
char *uri = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
if (!package || !provider || !uri) {
NS_WARNING("Malformed chrome manifest, locale entry.");
continue;
}
nsCOMPtr<nsIURI> resolved;
rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
getter_AddRefs(resolved));
if (NS_FAILED(rv))
continue;
PackageEntry* entry =
NS_STATIC_CAST(PackageEntry*, PL_DHashTableOperate(&mPackagesHash,
& (const nsACString&) nsDependentCString(package),
PL_DHASH_ADD));
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
entry->locales.SetBase(nsDependentCString(provider), resolved);
}
else if (!strcmp(token, "skin")) {
char *package = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
char *provider = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
char *uri = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
if (!package || !provider || !uri) {
NS_WARNING("Malformed chrome manifest, locale entry.");
continue;
}
nsCOMPtr<nsIURI> resolved;
rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
getter_AddRefs(resolved));
if (NS_FAILED(rv))
continue;
Bit checkin for bug 68045, r/sr=waterson&shaver, second attempt. It all works for me on optimized and debug gcc2.96, rh7.1. - Better failure codes from nsXULPrototypeScript::Deserialize. - Call nsXULDocument::AbortFastLoads after nsXULPrototypeScript::Serialize failure, instead of just nulling the FastLoad service's output stream. - Expose nsXULDocument::AbortFastLoads via nsIXULPrototypeCache, for use from nsChromeProtocolHandler.cpp. AbortFastLoads flushes the XUL cache now, for good measure. - The needless "Current" adjective in nsIFastLoadService attribute and method names is no more. - Add a do_GetFastLoadService() helper, to use CID instead of contractid, and to let the compiler consolidate the static inline CID. - Add "nglayout.debug.checksum_xul_fastload_file" pref so people can do without the checksum verification step when reading a FastLoad file. - Verify the FastLoad file checksum, by default. Also, cache it in the FastLoad service so we don't recompute it when re-opening the FastLoad file as mailnews and other top-levels start up. Fill the checksum cache in EndFastLoad, when the last pseudo-concurrent top-level finishes loading. My hope to compute the checksum while writing the FastLoad file ran afoul of misordered writes. The old code to checksum the in-memory nsFastLoadHeader also was broken on little endian platforms. Now all checksumming is done via a separate read pass over the complete file, save for the header's checksum field, which is summed as if it contained zero. - Track and check FastLoad file dependencies. This required groveling with a bunch of Necko interfaces in nsChromeProtocolHandler::NewChannel -- read it and weep. Dependency checking, as well as checksum access and computation, use better-factored nsIFastLoad{File,Read,Write}Control interfaces. - nsBufferedStream::Seek wasn't flushing the buffer when seeking backward within the buffer, but it must, because mCursor bounds the amount to write if the buffer contains the end of file. - Add an unbufferedStream readonly attribute to nsIStreamBufferAccess, so we don't have to screw around with the bufferying layer when checksumming. Also implement nsIStreamBufferAccess in nsBufferedOutputStream. - nsISeekableOutputStream was bogus, based on a bad state I had put the nsBufferedOutputStream code in on its way from being completely broken when you seek backwards outside of the buffer. Removing this interface required using nsIFastLoadFileIO in nsFastLoadFileWriter, and it also required careful ordering of Close calls (the Reader must close after the Writer or Updater, so that the Reader's underlying, unbuffered input stream can be read by nsFastLoadFileWriter::Close to compute the checksum. - Miscellaneous tab/indentation, comment typo, bracing, if( => if ( style, nsnull vs. 0, useless variable elimination, tortured control flow, AutoString instead of String, and gratuitous ; after nsISupportsUtils.h macro call cleanups.
2001-08-21 20:51:34 +00:00
PackageEntry* entry =
NS_STATIC_CAST(PackageEntry*, PL_DHashTableOperate(&mPackagesHash,
& (const nsACString&) nsDependentCString(package),
PL_DHASH_ADD));
if (!entry)
return NS_ERROR_OUT_OF_MEMORY;
entry->skins.SetBase(nsDependentCString(provider), resolved);
}
else if (!strcmp(token, "overlay")) {
if (aSkinOnly) {
NS_WARNING("Skin manifest contained overlay registration. Ignoring.");
continue;
}
char *base = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
char *overlay = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
if (!base || !overlay)
continue;
nsCOMPtr<nsIURI> baseuri, overlayuri;
rv = io->NewURI(nsDependentCString(base), nsnull, nsnull,
getter_AddRefs(baseuri));
rv |= io->NewURI(nsDependentCString(overlay), nsnull, nsnull,
getter_AddRefs(overlayuri));
if (NS_FAILED(rv)) {
NS_WARNING("Could not make URIs for overlay directive. Ignoring.");
continue;
}
2001-05-17 02:02:51 +00:00
mOverlayHash.Add(baseuri, overlayuri);
}
else if (!strcmp(token, "style")) {
char *base = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
char *overlay = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
if (!base || !overlay)
continue;
nsCOMPtr<nsIURI> baseuri, overlayuri;
rv = io->NewURI(nsDependentCString(base), nsnull, nsnull,
getter_AddRefs(baseuri));
rv |= io->NewURI(nsDependentCString(overlay), nsnull, nsnull,
getter_AddRefs(overlayuri));
if (NS_FAILED(rv))
continue;
mStyleHash.Add(baseuri, overlayuri);
2001-05-17 02:02:51 +00:00
}
else {
NS_WARNING("Unrecognized chrome manifest instruction ignored.");
}
}
2001-05-17 02:02:51 +00:00
return NS_OK;
2001-05-17 02:02:51 +00:00
}