Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Protected Attributes | Static Protected Attributes | Private Member Functions | Friends
nsXULPrototypeCache Class Reference
Inheritance diagram for nsXULPrototypeCache:
Inheritance graph
[legend]
Collaboration diagram for nsXULPrototypeCache:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER NS_IMETHOD 
GetPrototype (nsIURI *aURI, nsIXULPrototypeDocument **_result)
NS_IMETHOD PutPrototype (nsIXULPrototypeDocument *aDocument)
NS_IMETHOD FlushPrototypes ()
NS_IMETHOD GetStyleSheet (nsIURI *aURI, nsICSSStyleSheet **_result)
NS_IMETHOD PutStyleSheet (nsICSSStyleSheet *aStyleSheet)
NS_IMETHOD FlushStyleSheets ()
NS_IMETHOD GetScript (nsIURI *aURI, void **aScriptObject)
NS_IMETHOD PutScript (nsIURI *aURI, void *aScriptObject)
NS_IMETHOD FlushScripts ()
NS_IMETHOD GetXBLDocumentInfo (nsIURI *aURL, nsIXBLDocumentInfo **_result)
NS_IMETHOD PutXBLDocumentInfo (nsIXBLDocumentInfo *aDocumentInfo)
NS_IMETHOD FlushXBLInformation ()
NS_IMETHOD Flush ()
 Flush the cache; remove all XUL prototype documents, style sheets, and scripts.
NS_IMETHOD GetEnabled (PRBool *aIsEnabled)
 Determine if the prototype cache is enabled.
NS_IMETHOD AbortFastLoads ()
 Stop the FastLoad process abruptly, removing the FastLoad file.
NS_IMETHOD GetFastLoadService (nsIFastLoadService **aResult)
 Retrieve the FastLoad service.
NS_IMETHOD RemoveFromFastLoadSet (nsIURI *aDocumentURI)
 Remove a XULDocument from the set of loading documents.
NS_IMETHOD WritePrototype (nsIXULPrototypeDocument *aPrototypeDocument)
 Write Prototype Document to FastLoad file.
 NS_DEFINE_STATIC_IID_ACCESSOR (NS_IXULPROTOTYPECACHE_IID)

Protected Member Functions

 nsXULPrototypeCache ()
virtual ~nsXULPrototypeCache ()
void FlushSkinFiles ()
JSRuntimeGetJSRuntime ()
nsresult StartFastLoad (nsIURI *aDocumentURI)
nsresult StartFastLoadingURI (nsIURI *aURI, PRInt32 aDirectionFlags)

Protected Attributes

nsInterfaceHashtable
< nsURIHashKey,
nsIXULPrototypeDocument
mPrototypeTable
nsInterfaceHashtable
< nsURIHashKey,
nsICSSStyleSheet
mStyleSheetTable
nsDataHashtable< nsURIHashKey,
void * > 
mScriptTable
nsInterfaceHashtable
< nsURIHashKey,
nsIXBLDocumentInfo
mXBLDocTable
JSRuntimemJSRuntime
nsDataHashtable< nsURIHashKey,
PRUint32
mFastLoadURITable

Static Protected Attributes

static nsIFastLoadServicegFastLoadService = nsnull
static nsIFilegFastLoadFile = nsnull

Private Member Functions

void observe (in nsISupports aSubject, in string aTopic, in wstring aData)
 Observe will be called when there is a notification for the topic |aTopic|.

Friends

NS_IMETHODIMP NS_NewXULPrototypeCache (nsISupports *aOuter, REFNSIID aIID, void **aResult)

Detailed Description

Definition at line 77 of file nsXULPrototypeCache.cpp.


Constructor & Destructor Documentation

Definition at line 168 of file nsXULPrototypeCache.cpp.

Definition at line 174 of file nsXULPrototypeCache.cpp.

{
    FlushScripts();

    NS_IF_RELEASE(gFastLoadService); // don't need ReleaseService nowadays!
    NS_IF_RELEASE(gFastLoadFile);
}

Here is the call graph for this function:


Member Function Documentation

Stop the FastLoad process abruptly, removing the FastLoad file.

Implements nsIXULPrototypeCache.

Definition at line 506 of file nsXULPrototypeCache.cpp.

{
#ifdef DEBUG_brendan
    NS_BREAK();
#endif

    // Save a strong ref to the FastLoad file, so we can remove it after we
    // close open streams to it.
    nsCOMPtr<nsIFile> file = gFastLoadFile;

    // Flush the XUL cache for good measure, in case we cached a bogus/downrev
    // script, somehow.
    Flush();

    // Clear the FastLoad set
    mFastLoadURITable.Clear();

    if (! gFastLoadService)
        return NS_OK;

    // Fetch the current input (if FastLoad file existed) or output (if we're
    // creating the FastLoad file during this app startup) stream.
    nsCOMPtr<nsIObjectInputStream> objectInput;
    nsCOMPtr<nsIObjectOutputStream> objectOutput;
    gFastLoadService->GetInputStream(getter_AddRefs(objectInput));
    gFastLoadService->GetOutputStream(getter_AddRefs(objectOutput));

    if (objectOutput) {
        gFastLoadService->SetOutputStream(nsnull);

        if (NS_SUCCEEDED(objectOutput->Close()) && gChecksumXULFastLoadFile)
            gFastLoadService->CacheChecksum(gFastLoadFile,
                                            objectOutput);
    }

    if (objectInput) {
        // If this is the last of one or more XUL master documents loaded
        // together at app startup, close the FastLoad service's singleton
        // input stream now.
        gFastLoadService->SetInputStream(nsnull);
        objectInput->Close();
    }

    // Now rename or remove the file.
    if (file) {
#ifdef DEBUG
        // Remove any existing Aborted.mfasl files generated in previous runs.
        nsCOMPtr<nsIFile> existingAbortedFile;
        file->Clone(getter_AddRefs(existingAbortedFile));
        if (existingAbortedFile) {
            existingAbortedFile->SetLeafName(NS_LITERAL_STRING("Aborted.mfasl"));
            PRBool fileExists = PR_FALSE;
            existingAbortedFile->Exists(&fileExists);
            if (fileExists)
                existingAbortedFile->Remove(PR_FALSE);
        }
        file->MoveToNative(nsnull, NS_LITERAL_CSTRING("Aborted.mfasl"));
#else
        file->Remove(PR_FALSE);
#endif
    }

    // If the list is empty now, the FastLoad process is done.
    NS_RELEASE(gFastLoadService);
    NS_RELEASE(gFastLoadFile);

    return NS_OK;
}

Here is the call graph for this function:

Flush the cache; remove all XUL prototype documents, style sheets, and scripts.

Implements nsIXULPrototypeCache.

Here is the caller graph for this function:

Implements nsIXULPrototypeCache.

Implements nsIXULPrototypeCache.

Here is the caller graph for this function:

Implements nsIXULPrototypeCache.

Implements nsIXULPrototypeCache.

NS_IMETHOD nsXULPrototypeCache::GetEnabled ( PRBool aIsEnabled) [virtual]

Determine if the prototype cache is enabled.

Implements nsIXULPrototypeCache.

Retrieve the FastLoad service.

Implements nsIXULPrototypeCache.

NS_DECL_ISUPPORTS NS_DECL_NSIOBSERVER NS_IMETHOD nsXULPrototypeCache::GetPrototype ( nsIURI aURI,
nsIXULPrototypeDocument **  _result 
) [virtual]

Implements nsIXULPrototypeCache.

NS_IMETHOD nsXULPrototypeCache::GetScript ( nsIURI aURI,
void **  aScriptObject 
) [virtual]

Implements nsIXULPrototypeCache.

NS_IMETHOD nsXULPrototypeCache::GetStyleSheet ( nsIURI aURI,
nsICSSStyleSheet **  _result 
) [virtual]

Implements nsIXULPrototypeCache.

Implements nsIXULPrototypeCache.

void nsIObserver::observe ( in nsISupports  aSubject,
in string  aTopic,
in wstring  aData 
) [inherited]

Observe will be called when there is a notification for the topic |aTopic|.

This assumes that the object implementing this interface has been registered with an observer service such as the nsIObserverService.

If you expect multiple topics/subjects, the impl is responsible for filtering.

You should not modify, add, remove, or enumerate notifications in the implemention of observe.

Parameters:
aSubject: Notification specific interface pointer.
aTopic: The notification topic or subject.
aData: Notification specific wide string. subject event.

Implements nsIXULPrototypeCache.

NS_IMETHOD nsXULPrototypeCache::PutScript ( nsIURI aURI,
void aScriptObject 
) [virtual]

Implements nsIXULPrototypeCache.

Implements nsIXULPrototypeCache.

Implements nsIXULPrototypeCache.

Remove a XULDocument from the set of loading documents.

Implements nsIXULPrototypeCache.

Definition at line 577 of file nsXULPrototypeCache.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULPrototypeCache::StartFastLoad ( nsIURI aDocumentURI) [protected]

Definition at line 780 of file nsXULPrototypeCache.cpp.

{
    nsresult rv;

    nsCAutoString path;
    aURI->GetPath(path);
    if (!StringEndsWith(path, NS_LITERAL_CSTRING(".xul")))
        return NS_ERROR_NOT_AVAILABLE;

    // Test gFastLoadFile to decide whether this is the first nsXULDocument
    // participating in FastLoad.  If gFastLoadFile is non-null, this document
    // must not be first, but it can join the FastLoad process.  Examples of
    // multiple master documents participating include hiddenWindow.xul and
    // navigator.xul on the Mac, and multiple-app-component (e.g., mailnews
    // and browser) startup due to command-line arguments.
    //
    // XXXbe we should attempt to update the FastLoad file after startup!
    //
    // XXXbe we do not yet use nsFastLoadPtrs, but once we do, we must keep
    // the FastLoad input stream open for the life of the app.
    if (gFastLoadService && gFastLoadFile) {
        mFastLoadURITable.Put(aURI, 1);

        return NS_OK;
    }

    // Use a local to refer to the service till we're sure we succeeded, then
    // commit to gFastLoadService.  Same for gFastLoadFile, which is used to
    // delete the FastLoad file on abort.
    nsCOMPtr<nsIFastLoadService> fastLoadService(do_GetFastLoadService());
    if (! fastLoadService)
        return NS_ERROR_FAILURE;

    gDisableXULFastLoad =
        nsContentUtils::GetBoolPref(kDisableXULFastLoadPref,
                                    gDisableXULFastLoad);
    gChecksumXULFastLoadFile =
        nsContentUtils::GetBoolPref(kChecksumXULFastLoadFilePref,
                                    gChecksumXULFastLoadFile);
    nsContentUtils::RegisterPrefCallback(kDisableXULFastLoadPref,
                                         FastLoadPrefChangedCallback,
                                         nsnull);
    nsContentUtils::RegisterPrefCallback(kChecksumXULFastLoadFilePref,
                                         FastLoadPrefChangedCallback,
                                         nsnull);

    if (gDisableXULFastLoad)
        return NS_ERROR_NOT_AVAILABLE;

    // Get the chrome directory to validate against the one stored in the
    // FastLoad file, or to store there if we're generating a new file.
    nsCOMPtr<nsIFile> chromeDir;
    rv = NS_GetSpecialDirectory(NS_APP_CHROME_DIR, getter_AddRefs(chromeDir));
    if (NS_FAILED(rv))
        return rv;
    nsCAutoString chromePath;
    rv = chromeDir->GetNativePath(chromePath);
    if (NS_FAILED(rv))
        return rv;

    nsCOMPtr<nsIFile> file;
    rv = fastLoadService->NewFastLoadFile(XUL_FASTLOAD_FILE_BASENAME,
                                          getter_AddRefs(file));
    if (NS_FAILED(rv))
        return rv;

    // Give the FastLoad service an object by which it can get or create a
    // file output stream given an input stream on the same file.
    nsXULFastLoadFileIO* xio = new nsXULFastLoadFileIO(file);
    nsCOMPtr<nsIFastLoadFileIO> io = NS_STATIC_CAST(nsIFastLoadFileIO*, xio);
    if (! io)
        return NS_ERROR_OUT_OF_MEMORY;
    fastLoadService->SetFileIO(io);

    nsCOMPtr<nsIXULChromeRegistry> chromeReg(do_GetService(NS_CHROMEREGISTRY_CONTRACTID, &rv));
    if (NS_FAILED(rv))
        return rv;

    // XXXbe we assume the first package's locale is the same as the locale of
    // all subsequent packages of FastLoaded chrome URIs....
    nsCAutoString package;
    rv = aURI->GetHost(package);
    if (NS_FAILED(rv))
        return rv;

    nsCAutoString locale;
    rv = chromeReg->GetSelectedLocale(package, locale);
    if (NS_FAILED(rv))
        return rv;

    // Try to read an existent FastLoad file.
    PRBool exists = PR_FALSE;
    if (NS_SUCCEEDED(file->Exists(&exists)) && exists) {
        nsCOMPtr<nsIInputStream> input;
        rv = io->GetInputStream(getter_AddRefs(input));
        if (NS_FAILED(rv))
            return rv;

        nsCOMPtr<nsIObjectInputStream> objectInput;
        rv = fastLoadService->NewInputStream(input, getter_AddRefs(objectInput));

        if (NS_SUCCEEDED(rv)) {
            if (gChecksumXULFastLoadFile) {
                nsCOMPtr<nsIFastLoadReadControl>
                    readControl(do_QueryInterface(objectInput));
                if (readControl) {
                    // Verify checksum, using the fastLoadService's checksum
                    // cache to avoid computing more than once per session.
                    PRUint32 checksum;
                    rv = readControl->GetChecksum(&checksum);
                    if (NS_SUCCEEDED(rv)) {
                        PRUint32 verified;
                        rv = fastLoadService->ComputeChecksum(file,
                                                               readControl,
                                                               &verified);
                        if (NS_SUCCEEDED(rv) && verified != checksum) {
#ifdef DEBUG
                            printf("bad FastLoad file checksum\n");
#endif
                            rv = NS_ERROR_FAILURE;
                        }
                    }
                }
            }

            if (NS_SUCCEEDED(rv)) {
                // Get the XUL fastload file version number, which should be
                // decremented whenever the XUL-specific file format changes
                // (see public/nsIXULPrototypeCache.h for the #define).
                PRUint32 xulFastLoadVersion, jsByteCodeVersion;
                rv = objectInput->Read32(&xulFastLoadVersion);
                rv |= objectInput->Read32(&jsByteCodeVersion);
                if (NS_SUCCEEDED(rv)) {
                    if (xulFastLoadVersion != XUL_FASTLOAD_FILE_VERSION ||
                        jsByteCodeVersion != JSXDR_BYTECODE_VERSION) {
#ifdef DEBUG
                        printf((xulFastLoadVersion != XUL_FASTLOAD_FILE_VERSION)
                               ? "bad FastLoad file version\n"
                               : "bad JS bytecode version\n");
#endif
                        rv = NS_ERROR_UNEXPECTED;
                    } else {
                        nsCAutoString fileChromePath, fileLocale;

                        rv = objectInput->ReadCString(fileChromePath);
                        rv |= objectInput->ReadCString(fileLocale);
                        if (NS_SUCCEEDED(rv) &&
                            (!fileChromePath.Equals(chromePath) ||
                             !fileLocale.Equals(locale))) {
                            rv = NS_ERROR_UNEXPECTED;
                        }
                    }
                }
            }
        }

        if (NS_SUCCEEDED(rv)) {
            fastLoadService->SetInputStream(objectInput);
        } else {
            // NB: we must close before attempting to remove, for non-Unix OSes
            // that can't do open-unlink.
            if (objectInput)
                objectInput->Close();
            else
                input->Close();
            xio->mInputStream = nsnull;

#ifdef DEBUG
            file->MoveToNative(nsnull, NS_LITERAL_CSTRING("Invalid.mfasl"));
#else
            file->Remove(PR_FALSE);
#endif
            exists = PR_FALSE;
        }
    }

    // FastLoad file not found, or invalid: write a new one.
    if (! exists) {
        nsCOMPtr<nsIOutputStream> output;
        rv = io->GetOutputStream(getter_AddRefs(output));
        if (NS_FAILED(rv))
            return rv;

        nsCOMPtr<nsIObjectOutputStream> objectOutput;
        rv = fastLoadService->NewOutputStream(output,
                                              getter_AddRefs(objectOutput));
        if (NS_SUCCEEDED(rv)) {
            rv = objectOutput->Write32(XUL_FASTLOAD_FILE_VERSION);
            rv |= objectOutput->Write32(JSXDR_BYTECODE_VERSION);
            rv |= objectOutput->WriteStringZ(chromePath.get());
            rv |= objectOutput->WriteStringZ(locale.get());
        }

        // Remove here even though some errors above will lead to a FastLoad
        // file invalidation.  Other errors (failure to note the dependency on
        // installed-chrome.txt, e.g.) will not cause invalidation, and we may
        // as well tidy up now.
        if (NS_FAILED(rv)) {
            if (objectOutput)
                objectOutput->Close();
            else
                output->Close();
            xio->mOutputStream = nsnull;

            file->Remove(PR_FALSE);
            return NS_ERROR_FAILURE;
        }

        fastLoadService->SetOutputStream(objectOutput);
    }

    // Success!  Insert this URI into the mFastLoadURITable
    // and commit locals to globals.
    mFastLoadURITable.Put(aURI, 1);

    NS_ADDREF(gFastLoadService = fastLoadService);
    NS_ADDREF(gFastLoadFile = file);
    return NS_OK;
}

Here is the call graph for this function:

nsresult nsXULPrototypeCache::StartFastLoadingURI ( nsIURI aURI,
PRInt32  aDirectionFlags 
) [protected]

Definition at line 668 of file nsXULPrototypeCache.cpp.

{
    nsresult rv;

    nsCAutoString urlspec;
    rv = aURI->GetAsciiSpec(urlspec);
    if (NS_FAILED(rv)) return rv;

    // If StartMuxedDocument returns NS_ERROR_NOT_AVAILABLE, then
    // we must be reading the file, and urlspec was not associated
    // with any multiplexed stream in it.  The FastLoad service
    // will therefore arrange to update the file, writing new data
    // at the end while old (available) data continues to be read
    // from the pre-existing part of the file.
    return gFastLoadService->StartMuxedDocument(aURI, urlspec.get(), aDirectionFlags);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Write Prototype Document to FastLoad file.

Implements nsIXULPrototypeCache.

Definition at line 587 of file nsXULPrototypeCache.cpp.

{
    nsresult rv = NS_OK, rv2 = NS_OK;

    // We're here before the FastLoad service has been initialized, probably because
    // of the profile manager. Bail quietly, don't worry, we'll be back later.
    if (! gFastLoadService)
        return NS_OK;

    // Fetch the current input (if FastLoad file existed) or output (if we're
    // creating the FastLoad file during this app startup) stream.
    nsCOMPtr<nsIObjectInputStream> objectInput;
    nsCOMPtr<nsIObjectOutputStream> objectOutput;
    gFastLoadService->GetInputStream(getter_AddRefs(objectInput));
    gFastLoadService->GetOutputStream(getter_AddRefs(objectOutput));

    nsCOMPtr<nsIURI> protoURI;
    aPrototypeDocument->GetURI(getter_AddRefs(protoURI));

    // Remove this document from the FastLoad table. We use the table's
    // emptiness instead of a counter to decide when the FastLoad process
    // has completed. When complete, we can write footer details to the
    // FastLoad file.
    RemoveFromFastLoadSet(protoURI);

    PRInt32 count = mFastLoadURITable.Count();

    if (objectOutput) {
        rv = StartFastLoadingURI(protoURI, nsIFastLoadService::NS_FASTLOAD_WRITE);
        if (NS_SUCCEEDED(rv)) {
            // Re-select the URL of the current prototype, as out-of-line script loads
            // may have changed
            nsCOMPtr<nsIURI> oldURI;
            gFastLoadService->SelectMuxedDocument(protoURI, getter_AddRefs(oldURI));

            aPrototypeDocument->Write(objectOutput);

            gFastLoadService->EndMuxedDocument(protoURI);
        }

        // If this is the last of one or more XUL master documents loaded
        // together at app startup, close the FastLoad service's singleton
        // output stream now.
        //
        // NB: we must close input after output, in case the output stream
        // implementation needs to read from the input stream, to compute a
        // FastLoad file checksum.  In that case, the implementation used
        // nsIFastLoadFileIO to get the corresponding input stream for this
        // output stream.
        if (count == 0) {
            gFastLoadService->SetOutputStream(nsnull);
            rv = objectOutput->Close();

            if (NS_SUCCEEDED(rv) && gChecksumXULFastLoadFile) {
                rv = gFastLoadService->CacheChecksum(gFastLoadFile,
                                                     objectOutput);
            }
        }
    }

    if (objectInput) {
        // If this is the last of one or more XUL master documents loaded
        // together at app startup, close the FastLoad service's singleton
        // input stream now.
        if (count == 0) {
            gFastLoadService->SetInputStream(nsnull);
            rv2 = objectInput->Close();
        }
    }

    // If the list is empty now, the FastLoad process is done.
    if (count == 0) {
        NS_RELEASE(gFastLoadService);
        NS_RELEASE(gFastLoadFile);
    }

    return NS_FAILED(rv) ? rv : rv2;
}

Here is the call graph for this function:


Friends And Related Function Documentation

NS_IMETHODIMP NS_NewXULPrototypeCache ( nsISupports *  aOuter,
REFNSIID  aIID,
void **  aResult 
) [friend]

Member Data Documentation

Definition at line 134 of file nsXULPrototypeCache.cpp.

Definition at line 133 of file nsXULPrototypeCache.cpp.

Definition at line 131 of file nsXULPrototypeCache.cpp.

Definition at line 126 of file nsXULPrototypeCache.cpp.

Definition at line 121 of file nsXULPrototypeCache.cpp.

Definition at line 123 of file nsXULPrototypeCache.cpp.

Definition at line 122 of file nsXULPrototypeCache.cpp.

Definition at line 124 of file nsXULPrototypeCache.cpp.


The documentation for this class was generated from the following file: