Index: trunk/src/libs/xpcom18a4/Config.kmk
===================================================================
--- trunk/src/libs/xpcom18a4/Config.kmk	(revision 101807)
+++ trunk/src/libs/xpcom18a4/Config.kmk	(revision 101808)
@@ -429,6 +429,4 @@
 	xpcom/io/nsIByteArrayInputStream.idl \
 	xpcom/io/nsISeekableStream.idl \
-	xpcom/io/nsIFastLoadFileControl.idl \
-	xpcom/io/nsIFastLoadService.idl \
 	xpcom/io/nsIInputStreamTee.idl \
 	xpcom/io/nsIMultiplexInputStream.idl \
Index: trunk/src/libs/xpcom18a4/Makefile.kmk
===================================================================
--- trunk/src/libs/xpcom18a4/Makefile.kmk	(revision 101807)
+++ trunk/src/libs/xpcom18a4/Makefile.kmk	(revision 101808)
@@ -300,6 +300,4 @@
 	xpcom/base/nsError.h \
 	xpcom/threads/nsEventQueueUtils.h \
-	xpcom/io/nsFastLoadPtr.h \
-	xpcom/io/nsFastLoadService.h \
 	xpcom/ds/nsFixedSizeAllocator.h \
 	xpcom/ds/nsHashKeys.h \
@@ -669,6 +667,4 @@
 	xpcom/io/nsByteArrayInputStream.cpp \
 	xpcom/io/nsDirectoryService.cpp \
-	xpcom/io/nsFastLoadFile.cpp \
-	xpcom/io/nsFastLoadService.cpp \
 	xpcom/io/nsInputStreamTee.cpp \
 	xpcom/io/nsLinebreakConverter.cpp \
Index: trunk/src/libs/xpcom18a4/xpcom/build/nsXPComInit.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/xpcom/build/nsXPComInit.cpp	(revision 101807)
+++ trunk/src/libs/xpcom18a4/xpcom/build/nsXPComInit.cpp	(revision 101808)
@@ -101,6 +101,4 @@
 #include "nsMultiplexInputStream.h"
 
-#include "nsFastLoadService.h"
-
 #include "nsAtomService.h"
 #include "nsAtomTable.h"
@@ -408,5 +406,4 @@
     COMPONENT(MULTIPLEXINPUTSTREAM, nsMultiplexInputStreamConstructor),
 
-    COMPONENT(FASTLOADSERVICE, nsFastLoadService::Create),
     COMPONENT(VARIANT, nsVariantConstructor),
     COMPONENT(INTERFACEINFOMANAGER_SERVICE, nsXPTIInterfaceInfoManagerGetSingleton),
Index: trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadFile.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadFile.cpp	(revision 101807)
+++ 	(revision )
@@ -1,2581 +1,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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/
- *
- * 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.
- *
- * The Original Code is Mozilla FastLoad code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Brendan Eich <brendan@mozilla.org> (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of 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 ***** */
-
-#include <string.h>
-#include "prtypes.h"
-#include "nscore.h"
-#include "nsDebug.h"
-#include "nsEnumeratorUtils.h"
-#include "nsMemory.h"
-#include "nsXPIDLString.h"
-#include "nsString.h"
-#include "nsReadableUtils.h"
-
-#include "nsIComponentManager.h"
-#include "nsIFile.h"
-#include "nsILocalFile.h"
-#include "nsISeekableStream.h"
-#include "nsISerializable.h"
-#include "nsIStreamBufferAccess.h"
-
-#include "nsBinaryStream.h"
-#include "nsFastLoadFile.h"
-#include "nsInt64.h"
-
-#ifdef DEBUG_brendan
-# define METERING
-# define DEBUG_MUX
-#endif
-
-#ifdef METERING
-# define METER(x)       x
-#else
-# define METER(x)       /* nothing */
-#endif
-
-#ifdef DEBUG_MUX
-# include <stdio.h>
-# include <stdarg.h>
-
-static void trace_mux(char mode, const char *format, ...)
-{
-    va_list ap;
-    static FILE *tfp;
-    if (!tfp) {
-        char tfn[16];
-        sprintf(tfn, "/tmp/mux.%ctrace", mode);
-        tfp = fopen(tfn, "w");
-        if (!tfp)
-            return;
-        setvbuf(tfp, NULL, _IOLBF, 0);
-    }
-    va_start(ap, format);
-    vfprintf(tfp, format, ap);
-    va_end(ap);
-}
-
-# define TRACE_MUX(args) trace_mux args
-#else
-# define TRACE_MUX(args) /* nothing */
-#endif
-
-/*
- * Fletcher's 16-bit checksum, using 32-bit two's-complement arithmetic.
- */
-#define FOLD_ONES_COMPLEMENT_CARRY(X)   ((X) = ((X) & 0xffff) + ((X) >> 16))
-#define ONES_COMPLEMENT_ACCUMULATE(X,Y) (X) += (Y); if ((X) & 0x80000000)     \
-                                        FOLD_ONES_COMPLEMENT_CARRY(X)
-#define FLETCHER_ACCUMULATE(A,B,U)      ONES_COMPLEMENT_ACCUMULATE(A, U);     \
-                                        ONES_COMPLEMENT_ACCUMULATE(B, A)
-
-PR_IMPLEMENT(PRUint32)
-NS_AccumulateFastLoadChecksum(PRUint32 *aChecksum,
-                              const PRUint8* aBuffer,
-                              PRUint32 aLength,
-                              PRBool aLastBuffer)
-{
-    PRUint32 C = *aChecksum;
-    PRUint32 A = C & 0xffff;
-    PRUint32 B = C >> 16;
-
-    PRUint16 U = 0;
-    if (aLength >= 4) {
-        PRBool odd = PRWord(aBuffer) & 1;
-        switch (PRWord(aBuffer) & 3) {
-          case 3:
-            U = (aBuffer[0] << 8) | aBuffer[1];
-            FLETCHER_ACCUMULATE(A, B, U);
-            U = aBuffer[2];
-            aBuffer += 3;
-            aLength -= 3;
-            break;
-
-          case 2:
-            U = (aBuffer[0] << 8) | aBuffer[1];
-            FLETCHER_ACCUMULATE(A, B, U);
-            U = 0;
-            aBuffer += 2;
-            aLength -= 2;
-            break;
-
-          case 1:
-            U = *aBuffer++;
-            aLength--;
-            break;
-        }
-
-        PRUint32 W;
-        if (odd) {
-            while (aLength > 3) {
-                W = *NS_REINTERPRET_CAST(const PRUint32*, aBuffer);
-                U <<= 8;
-#ifdef IS_BIG_ENDIAN
-                U |= W >> 24;
-                FLETCHER_ACCUMULATE(A, B, U);
-                U = PRUint16(W >> 8);
-                FLETCHER_ACCUMULATE(A, B, U);
-                U = W & 0xff;
-#else
-                U |= W & 0xff;
-                FLETCHER_ACCUMULATE(A, B, U);
-                U = PRUint16(W >> 8);
-                U = NS_SWAP16(U);
-                FLETCHER_ACCUMULATE(A, B, U);
-                U = W >> 24;
-#endif
-                aBuffer += 4;
-                aLength -= 4;
-            }
-            aBuffer--;      // we're odd, we didn't checksum the last byte
-            aLength++;
-        } else {
-            while (aLength > 3) {
-                W = *NS_REINTERPRET_CAST(const PRUint32*, aBuffer);
-#ifdef IS_BIG_ENDIAN
-                U = W >> 16;
-                FLETCHER_ACCUMULATE(A, B, U);
-                U = PRUint16(W);
-                FLETCHER_ACCUMULATE(A, B, U);
-#else
-                U = NS_SWAP16(W);
-                FLETCHER_ACCUMULATE(A, B, U);
-                U = W >> 16;
-                U = NS_SWAP16(W);
-                FLETCHER_ACCUMULATE(A, B, U);
-#endif
-                aBuffer += 4;
-                aLength -= 4;
-            }
-        }
-    }
-
-    if (aLastBuffer) {
-        NS_ASSERTION(aLength <= 4, "aLength botch");
-        switch (aLength) {
-          case 4:
-            U = (aBuffer[0] << 8) | aBuffer[1];
-            FLETCHER_ACCUMULATE(A, B, U);
-            U = (aBuffer[2] << 8) | aBuffer[3];
-            FLETCHER_ACCUMULATE(A, B, U);
-            break;
-
-          case 3:
-            U = (aBuffer[0] << 8) | aBuffer[1];
-            FLETCHER_ACCUMULATE(A, B, U);
-            U = aBuffer[2];
-            FLETCHER_ACCUMULATE(A, B, U);
-            break;
-
-          case 2:
-            U = (aBuffer[0] << 8) | aBuffer[1];
-            FLETCHER_ACCUMULATE(A, B, U);
-            break;
-
-          case 1:
-            U = aBuffer[0];
-            FLETCHER_ACCUMULATE(A, B, U);
-            break;
-        }
-
-        aLength = 0;
-    }
-
-    while (A >> 16)
-        FOLD_ONES_COMPLEMENT_CARRY(A);
-    while (B >> 16)
-        FOLD_ONES_COMPLEMENT_CARRY(B);
-
-    *aChecksum = (B << 16) | A;
-    return aLength;
-}
-
-PR_IMPLEMENT(PRUint32)
-NS_AddFastLoadChecksums(PRUint32 sum1, PRUint32 sum2, PRUint32 sum2ByteCount)
-{
-    PRUint32 A1 = sum1 & 0xffff;
-    PRUint32 B1 = sum1 >> 16;
-
-    PRUint32 A2 = sum2 & 0xffff;
-    PRUint32 B2 = sum2 >> 16;
-
-    PRUint32 A = A1 + A2;
-    while (A >> 16)
-        FOLD_ONES_COMPLEMENT_CARRY(A);
-
-    PRUint32 B = B2;
-    for (PRUint32 n = (sum2ByteCount + 1) / 2; n != 0; n--)
-        ONES_COMPLEMENT_ACCUMULATE(B, B1);
-    while (B >> 16)
-        FOLD_ONES_COMPLEMENT_CARRY(B);
-
-    return (B << 16) | A;
-}
-
-#undef FOLD_ONES_COMPLEMENT_CARRY
-#undef ONES_COMPLEMENT_ACCUMULATE
-#undef FLETCHER_ACCUMULATE
-
-static const char magic[] = MFL_FILE_MAGIC;
-
-// -------------------------- nsFastLoadFileReader --------------------------
-
-nsID nsFastLoadFileReader::nsFastLoadFooter::gDummyID;
-nsFastLoadFileReader::nsObjectMapEntry
-    nsFastLoadFileReader::nsFastLoadFooter::gDummySharpObjectEntry;
-
-NS_IMPL_ISUPPORTS_INHERITED5(nsFastLoadFileReader,
-                             nsBinaryInputStream,
-                             nsIObjectInputStream,
-                             nsIFastLoadFileControl,
-                             nsIFastLoadReadControl,
-                             nsISeekableStream,
-                             nsIFastLoadFileReader)
-
-MOZ_DECL_CTOR_COUNTER(nsFastLoadFileReader)
-
-nsresult
-nsFastLoadFileReader::ReadHeader(nsFastLoadHeader *aHeader)
-{
-    nsresult rv;
-    PRUint32 bytesRead;
-
-    rv = Read(NS_REINTERPRET_CAST(char*, aHeader), sizeof *aHeader, &bytesRead);
-    if (NS_FAILED(rv))
-        return rv;
-
-    if (bytesRead != sizeof *aHeader ||
-        memcmp(aHeader->mMagic, magic, MFL_FILE_MAGIC_SIZE)) {
-        return NS_ERROR_UNEXPECTED;
-    }
-
-    aHeader->mChecksum     = NS_SWAP32(aHeader->mChecksum);
-    aHeader->mVersion      = NS_SWAP32(aHeader->mVersion);
-    aHeader->mFooterOffset = NS_SWAP32(aHeader->mFooterOffset);
-    aHeader->mFileSize     = NS_SWAP32(aHeader->mFileSize);
-
-    return NS_OK;
-}
-
-// nsIFastLoadFileControl methods:
-
-NS_IMETHODIMP
-nsFastLoadFileReader::GetChecksum(PRUint32 *aChecksum)
-{
-    *aChecksum = mHeader.mChecksum;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::SetChecksum(PRUint32 aChecksum)
-{
-    mHeader.mChecksum = aChecksum;
-    return NS_OK;
-}
-
-struct nsStringMapEntry : public PLDHashEntryHdr {
-    const char*     mString;            // key, must come first
-    nsISupports*    mURI;               // for SelectMuxedDocument return value
-};
-
-struct nsDocumentMapEntry : public nsStringMapEntry {
-    PRUint32    mInitialSegmentOffset;  // offset of URI's first segment in file
-};
-
-struct nsDocumentMapReadEntry : public nsDocumentMapEntry {
-    PRUint32    mNextSegmentOffset;     // offset of URI's next segment to read
-    PRUint32    mBytesLeft : 31,        // bytes remaining in current segment
-                mNeedToSeek : 1;        // flag to defer Seek from Select to
-                                        // Read, in case there is no Read before
-                                        // another entry is Selected (to improve
-                                        // input stream buffer utilization)
-    PRInt64     mSaveOffset;            // in case demux schedule differs from
-                                        // mux schedule
-};
-
-PR_STATIC_CALLBACK(void)
-strmap_ClearEntry(PLDHashTable *aTable, PLDHashEntryHdr *aHdr)
-{
-    nsStringMapEntry* entry = NS_STATIC_CAST(nsStringMapEntry*, aHdr);
-
-    if (entry->mString)
-        nsMemory::Free((void*) entry->mString);
-    NS_IF_RELEASE(entry->mURI);
-    PL_DHashClearEntryStub(aTable, aHdr);
-}
-
-static const PLDHashTableOps strmap_DHashTableOps = {
-    PL_DHashAllocTable,
-    PL_DHashFreeTable,
-    PL_DHashGetKeyStub,
-    PL_DHashStringKey,
-    PL_DHashMatchStringKey,
-    PL_DHashMoveEntryStub,
-    strmap_ClearEntry,
-    PL_DHashFinalizeStub,
-    NULL
-};
-
-// An nsObjectMapEntry holds a strong reference to an XPCOM object, unless the
-// mObject member, when cast to NSFastLoadOID, has its MFL_OBJECT_DEF_TAG bit
-// set.  NB: we rely on the fact that an nsISupports* is never an odd pointer.
-struct nsObjectMapEntry : public PLDHashEntryHdr {
-    nsISupports*            mObject;        // key, must come first
-};
-
-// Fast mapping from URI object pointer back to spec-indexed document info.
-struct nsURIMapReadEntry : public nsObjectMapEntry {
-    nsDocumentMapReadEntry* mDocMapEntry;
-};
-
-PR_STATIC_CALLBACK(void)
-objmap_ClearEntry(PLDHashTable *aTable, PLDHashEntryHdr *aHdr)
-{
-    nsObjectMapEntry* entry = NS_STATIC_CAST(nsObjectMapEntry*, aHdr);
-
-    // Ignore tagged object ids stored as object pointer keys (the updater
-    // code does this).
-    if ((NS_PTR_TO_INT32(entry->mObject) & MFL_OBJECT_DEF_TAG) == 0)
-        NS_IF_RELEASE(entry->mObject);
-    PL_DHashClearEntryStub(aTable, aHdr);
-}
-
-static const PLDHashTableOps objmap_DHashTableOps = {
-    PL_DHashAllocTable,
-    PL_DHashFreeTable,
-    PL_DHashGetKeyStub,
-    PL_DHashVoidPtrKeyStub,
-    PL_DHashMatchEntryStub,
-    PL_DHashMoveEntryStub,
-    objmap_ClearEntry,
-    PL_DHashFinalizeStub,
-    NULL
-};
-
-NS_IMETHODIMP
-nsFastLoadFileReader::HasMuxedDocument(const char* aURISpec, PRBool *aResult)
-{
-    nsDocumentMapReadEntry* docMapEntry =
-        NS_STATIC_CAST(nsDocumentMapReadEntry*,
-                       PL_DHashTableOperate(&mFooter.mDocumentMap, aURISpec,
-                                            PL_DHASH_LOOKUP));
-
-    *aResult = PL_DHASH_ENTRY_IS_BUSY(docMapEntry);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::StartMuxedDocument(nsISupports* aURI, const char* aURISpec)
-{
-    nsDocumentMapReadEntry* docMapEntry =
-        NS_STATIC_CAST(nsDocumentMapReadEntry*,
-                       PL_DHashTableOperate(&mFooter.mDocumentMap, aURISpec,
-                                            PL_DHASH_LOOKUP));
-
-    // If the spec isn't in the map, return NS_ERROR_NOT_AVAILABLE so the
-    // FastLoad service can try for a file update.
-    if (PL_DHASH_ENTRY_IS_FREE(docMapEntry))
-        return NS_ERROR_NOT_AVAILABLE;
-
-    nsCOMPtr<nsISupports> key(do_QueryInterface(aURI));
-    nsURIMapReadEntry* uriMapEntry =
-        NS_STATIC_CAST(nsURIMapReadEntry*,
-                       PL_DHashTableOperate(&mFooter.mURIMap, key,
-                                            PL_DHASH_ADD));
-    if (!uriMapEntry)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    NS_ASSERTION(uriMapEntry->mDocMapEntry == nsnull,
-                 "URI mapped to two different specs?");
-    if (uriMapEntry->mDocMapEntry)
-        return NS_ERROR_UNEXPECTED;
-
-    docMapEntry->mURI = aURI;
-    NS_ADDREF(docMapEntry->mURI);
-    uriMapEntry->mObject = key;
-    NS_ADDREF(uriMapEntry->mObject);
-    uriMapEntry->mDocMapEntry = docMapEntry;
-    TRACE_MUX(('r', "start %p (%p) %s\n", aURI, key.get(), aURISpec));
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::SelectMuxedDocument(nsISupports* aURI,
-                                          nsISupports** aResult)
-{
-    nsresult rv;
-
-    // Find the given URI's entry and select it for more reading.
-    nsCOMPtr<nsISupports> key(do_QueryInterface(aURI));
-    nsURIMapReadEntry* uriMapEntry =
-        NS_STATIC_CAST(nsURIMapReadEntry*,
-                       PL_DHashTableOperate(&mFooter.mURIMap, key,
-                                            PL_DHASH_LOOKUP));
-
-    // If the URI isn't in the map, return NS_ERROR_NOT_AVAILABLE so the
-    // FastLoad service can try selecting the file updater.
-    if (PL_DHASH_ENTRY_IS_FREE(uriMapEntry))
-        return NS_ERROR_NOT_AVAILABLE;
-
-    // If we're interrupting another document's segment, save its offset so
-    // we can seek back when it's reselected.  If prevDocMapEntry->mNeedToSeek
-    // is set, that means the stream is not positioned for prevDocMapEntry, to
-    // avoid buffer thrashing.  See below in this function for more.
-    nsDocumentMapReadEntry* prevDocMapEntry = mCurrentDocumentMapEntry;
-    if (prevDocMapEntry &&
-        prevDocMapEntry->mBytesLeft &&
-        !prevDocMapEntry->mNeedToSeek) {
-        rv = Tell(&prevDocMapEntry->mSaveOffset);
-        if (NS_FAILED(rv))
-            return rv;
-    }
-
-    // It turns out we get a fair amount of redundant select calls, thanks to
-    // non-blocking hunks of data from the parser that are devoid of scripts.
-    // As more data gets FastLoaded, the number of these useless selects will
-    // decline.
-    nsDocumentMapReadEntry* docMapEntry = uriMapEntry->mDocMapEntry;
-    if (docMapEntry == prevDocMapEntry) {
-        TRACE_MUX(('r', "select prev %s same as current!\n",
-                   docMapEntry->mString));
-    }
-
-    // Invariant: docMapEntry->mBytesLeft implies docMapEntry->mSaveOffset has
-    // been set non-zero by the Tell call above.
-    else if (docMapEntry->mBytesLeft) {
-        NS_ASSERTION(docMapEntry->mSaveOffset != 0,
-                     "reselecting from multiplex at unsaved offset?");
-
-        // Defer Seek till Read, in case of "ping-pong" Selects without any
-        // intervening Reads, to avoid dumping the underlying mInputStream's
-        // input buffer for cases where alternate "pongs" fall in the same
-        // buffer.
-        docMapEntry->mNeedToSeek = PR_TRUE;
-    }
-
-    *aResult = prevDocMapEntry ? prevDocMapEntry->mURI : nsnull;
-    NS_IF_ADDREF(*aResult);
-
-    mCurrentDocumentMapEntry = docMapEntry;
-#ifdef DEBUG_MUX
-    PRInt64 currentSegmentOffset;
-    Tell(&currentSegmentOffset);
-    trace_mux('r', "select %p (%p) offset %ld\n",
-              aURI, key.get(), (long) currentSegmentOffset);
-#endif
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::EndMuxedDocument(nsISupports* aURI)
-{
-    nsCOMPtr<nsISupports> key(do_QueryInterface(aURI));
-    nsURIMapReadEntry* uriMapEntry =
-        NS_STATIC_CAST(nsURIMapReadEntry*,
-                       PL_DHashTableOperate(&mFooter.mURIMap, key,
-                                            PL_DHASH_LOOKUP));
-
-    // If the URI isn't in the map, return NS_ERROR_NOT_AVAILABLE so the
-    // FastLoad service can try to end a select on its file updater.
-    if (PL_DHASH_ENTRY_IS_FREE(uriMapEntry))
-        return NS_ERROR_NOT_AVAILABLE;
-
-    // Drop our ref to the URI object that was passed to StartMuxedDocument,
-    // we no longer need it, and we do not want to extend its lifetime.
-    if (uriMapEntry->mDocMapEntry)
-        NS_RELEASE(uriMapEntry->mDocMapEntry->mURI);
-
-    // Shrink the table if half the entries are removed sentinels.
-    PRUint32 size = PL_DHASH_TABLE_SIZE(&mFooter.mURIMap);
-    if (mFooter.mURIMap.removedCount >= (size >> 2))
-        PL_DHashTableOperate(&mFooter.mURIMap, key, PL_DHASH_REMOVE);
-    else
-        PL_DHashTableRawRemove(&mFooter.mURIMap, uriMapEntry);
-
-    TRACE_MUX(('r', "end %p (%p)\n", aURI, key.get()));
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::Read(char* aBuffer, PRUint32 aCount, PRUint32 *aBytesRead)
-{
-    nsresult rv;
-
-    nsDocumentMapReadEntry* entry = mCurrentDocumentMapEntry;
-    if (entry) {
-        // Don't call our Seek wrapper, as it clears mCurrentDocumentMapEntry.
-        nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mInputStream));
-        if (entry->mNeedToSeek) {
-            rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                                entry->mSaveOffset);
-            if (NS_FAILED(rv))
-                return rv;
-
-            entry->mNeedToSeek = PR_FALSE;
-        }
-
-        // Loop to handle empty segments, which may be generated by the
-        // writer, given Start A; Start B; Select A; Select B; write B data;
-        // multiplexing schedules, which do tend to occur given non-blocking
-        // i/o with LIFO scheduling.  XXXbe investigate LIFO issues
-        while (entry->mBytesLeft == 0) {
-            // Check for unexpected end of multiplexed stream.
-            NS_ASSERTION(entry->mNextSegmentOffset != 0,
-                         "document demuxed from FastLoad file more than once?");
-            if (entry->mNextSegmentOffset == 0)
-                return NS_ERROR_UNEXPECTED;
-
-            rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                                entry->mNextSegmentOffset);
-            if (NS_FAILED(rv))
-                return rv;
-
-            // Clear mCurrentDocumentMapEntry temporarily to avoid recursion.
-            mCurrentDocumentMapEntry = nsnull;
-
-            rv = Read32(&entry->mNextSegmentOffset);
-            if (NS_SUCCEEDED(rv)) {
-                PRUint32 bytesLeft = 0;
-                rv = Read32(&bytesLeft);
-                entry->mBytesLeft = bytesLeft;
-            }
-
-            mCurrentDocumentMapEntry = entry;
-            if (NS_FAILED(rv))
-                return rv;
-
-            NS_ASSERTION(entry->mBytesLeft >= 8, "demux segment length botch!");
-            entry->mBytesLeft -= 8;
-        }
-    }
-
-    rv = mInputStream->Read(aBuffer, aCount, aBytesRead);
-
-    if (NS_SUCCEEDED(rv) && entry) {
-        NS_ASSERTION(entry->mBytesLeft >= *aBytesRead, "demux Read underflow!");
-        entry->mBytesLeft -= *aBytesRead;
-
-#ifdef NS_DEBUG
-        // Invariant: !entry->mBytesLeft implies entry->mSaveOffset == 0.
-        if (entry->mBytesLeft == 0)
-            entry->mSaveOffset = 0;
-#endif
-    }
-    return rv;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
-                                   PRUint32 aCount, PRUint32 *aResult)
-{
-    nsDocumentMapReadEntry* entry = mCurrentDocumentMapEntry;
-
-    NS_ASSERTION(!entry || (!entry->mNeedToSeek && entry->mBytesLeft != 0),
-                 "ReadSegments called from above nsFastLoadFileReader layer?!");
-
-    nsresult rv = nsBinaryInputStream::ReadSegments(aWriter, aClosure, aCount,
-                                                    aResult);
-    if (NS_SUCCEEDED(rv) && entry) {
-        NS_ASSERTION(entry->mBytesLeft >= *aResult,
-                     "demux ReadSegments underflow!");
-        entry->mBytesLeft -= *aResult;
-
-#ifdef NS_DEBUG
-        // Invariant: !entry->mBytesLeft implies entry->mSaveOffset == 0.
-        if (entry->mBytesLeft == 0)
-            entry->mSaveOffset = 0;
-#endif
-    }
-    return rv;
-}
-
-/**
- * XXX tuneme
- */
-#define MFL_CHECKSUM_BUFSIZE    8192
-
-NS_IMETHODIMP
-nsFastLoadFileReader::ComputeChecksum(PRUint32 *aResult)
-{
-    nsCOMPtr<nsIInputStream> stream = mInputStream;
-
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(stream));
-    PRInt64 saveOffset;
-    nsresult rv = seekable->Tell(&saveOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCOMPtr<nsIStreamBufferAccess> bufferAccess(do_QueryInterface(stream));
-    if (bufferAccess) {
-        rv = bufferAccess->GetUnbufferedStream(getter_AddRefs(stream));
-        if (NS_FAILED(rv))
-            return rv;
-
-        seekable = do_QueryInterface(stream);
-        if (!seekable)
-            return NS_ERROR_UNEXPECTED;
-    }
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
-    if (NS_FAILED(rv))
-        return rv;
-
-    char buf[MFL_CHECKSUM_BUFSIZE];
-    PRUint32 len, rem;
-
-    rem = offsetof(nsFastLoadHeader, mChecksum);
-    rv = stream->Read(buf, rem, &len);
-    if (NS_FAILED(rv))
-        return rv;
-    if (len != rem)
-        return NS_ERROR_UNEXPECTED;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_CUR, 4);
-    if (NS_FAILED(rv))
-        return rv;
-    memset(buf + rem, 0, 4);
-    rem += 4;
-
-    PRUint32 checksum = 0;
-    while (NS_SUCCEEDED(rv = stream->Read(buf + rem, sizeof buf - rem, &len)) &&
-           len) {
-        len += rem;
-        rem = NS_AccumulateFastLoadChecksum(&checksum,
-                                            NS_REINTERPRET_CAST(PRUint8*, buf),
-                                            len,
-                                            PR_FALSE);
-        if (rem)
-            memcpy(buf, buf + len - rem, rem);
-    }
-    if (NS_FAILED(rv))
-        return rv;
-
-    if (rem) {
-        NS_AccumulateFastLoadChecksum(&checksum,
-                                      NS_REINTERPRET_CAST(PRUint8*, buf),
-                                      rem,
-                                      PR_TRUE);
-    }
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, saveOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aResult = checksum;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::GetDependencies(nsISimpleEnumerator* *aDependencies)
-{
-    return NS_NewArrayEnumerator(aDependencies, mFooter.mDependencies);
-}
-
-nsresult
-nsFastLoadFileReader::ReadFooter(nsFastLoadFooter *aFooter)
-{
-    nsresult rv;
-
-    rv = ReadFooterPrefix(aFooter);
-    if (NS_FAILED(rv))
-        return rv;
-
-    aFooter->mIDMap = new nsID[aFooter->mNumIDs];
-    if (!aFooter->mIDMap)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    PRUint32 i, n;
-    for (i = 0, n = aFooter->mNumIDs; i < n; i++) {
-        rv = ReadSlowID(&aFooter->mIDMap[i]);
-        if (NS_FAILED(rv))
-            return rv;
-    }
-
-    aFooter->mObjectMap = new nsObjectMapEntry[aFooter->mNumSharpObjects];
-    if (!aFooter->mObjectMap)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    for (i = 0, n = aFooter->mNumSharpObjects; i < n; i++) {
-        nsObjectMapEntry* entry = &aFooter->mObjectMap[i];
-
-        rv = ReadSharpObjectInfo(entry);
-        if (NS_FAILED(rv))
-            return rv;
-
-        entry->mReadObject = nsnull;
-        entry->mSkipOffset = 0;
-        entry->mSaveStrongRefCnt = entry->mStrongRefCnt;
-        entry->mSaveWeakRefCnt = entry->mWeakRefCnt;
-    }
-
-    if (!PL_DHashTableInit(&aFooter->mDocumentMap, &strmap_DHashTableOps,
-                           (void *)this, sizeof(nsDocumentMapReadEntry),
-                           aFooter->mNumMuxedDocuments)) {
-        aFooter->mDocumentMap.ops = nsnull;
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    if (!PL_DHashTableInit(&aFooter->mURIMap, &objmap_DHashTableOps,
-                           (void *)this, sizeof(nsURIMapReadEntry),
-                           aFooter->mNumMuxedDocuments)) {
-        aFooter->mURIMap.ops = nsnull;
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    for (i = 0, n = aFooter->mNumMuxedDocuments; i < n; i++) {
-        nsFastLoadMuxedDocumentInfo info;
-
-        rv = ReadMuxedDocumentInfo(&info);
-        if (NS_FAILED(rv))
-            return rv;
-
-        nsDocumentMapReadEntry* entry =
-            NS_STATIC_CAST(nsDocumentMapReadEntry*,
-                           PL_DHashTableOperate(&aFooter->mDocumentMap,
-                                                info.mURISpec,
-                                                PL_DHASH_ADD));
-        if (!entry) {
-            nsMemory::Free((void*) info.mURISpec);
-            return NS_ERROR_OUT_OF_MEMORY;
-        }
-
-        NS_ASSERTION(!entry->mString, "duplicate URISpec in MuxedDocumentMap");
-        entry->mString = info.mURISpec;
-        entry->mURI = nsnull;
-        entry->mInitialSegmentOffset = info.mInitialSegmentOffset;
-        entry->mNextSegmentOffset = info.mInitialSegmentOffset;
-        entry->mBytesLeft = 0;
-        entry->mNeedToSeek = PR_FALSE;
-        entry->mSaveOffset = 0;
-    }
-
-    nsCOMPtr<nsISupportsArray> readDeps;
-    rv = NS_NewISupportsArray(getter_AddRefs(readDeps));
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCAutoString filename;
-    for (i = 0, n = aFooter->mNumDependencies; i < n; i++) {
-        rv = ReadCString(filename);
-        if (NS_FAILED(rv))
-            return rv;
-
-        PRInt64 fastLoadMtime;
-        rv = Read64(NS_REINTERPRET_CAST(PRUint64*, &fastLoadMtime));
-        if (NS_FAILED(rv))
-            return rv;
-
-        nsCOMPtr<nsILocalFile> file;
-        rv = NS_NewNativeLocalFile(filename, PR_TRUE, getter_AddRefs(file));
-        if (NS_FAILED(rv))
-            return rv;
-
-        PRInt64 currentMtime;
-        rv = file->GetLastModifiedTime(&currentMtime);
-        if (NS_FAILED(rv))
-            return rv;
-
-        if (LL_NE(fastLoadMtime, currentMtime)) {
-#ifdef DEBUG
-            nsCAutoString path;
-            file->GetNativePath(path);
-            printf("%s mtime changed, invalidating FastLoad file\n",
-                   path.get());
-#endif
-            return NS_ERROR_FAILURE;
-        }
-
-        rv = readDeps->AppendElement(file);
-        if (NS_FAILED(rv))
-            return rv;
-    }
-
-    aFooter->mDependencies = readDeps;
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileReader::ReadFooterPrefix(nsFastLoadFooterPrefix *aFooterPrefix)
-{
-    nsresult rv;
-
-    rv = Read32(&aFooterPrefix->mNumIDs);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Read32(&aFooterPrefix->mNumSharpObjects);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Read32(&aFooterPrefix->mNumMuxedDocuments);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Read32(&aFooterPrefix->mNumDependencies);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileReader::ReadSlowID(nsID *aID)
-{
-    nsresult rv;
-
-    rv = Read32(&aID->m0);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Read16(&aID->m1);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Read16(&aID->m2);
-    if (NS_FAILED(rv))
-        return rv;
-
-    PRUint32 bytesRead;
-    rv = Read(NS_REINTERPRET_CAST(char*, aID->m3), sizeof aID->m3, &bytesRead);
-    if (NS_FAILED(rv))
-        return rv;
-
-    if (bytesRead != sizeof aID->m3)
-        return NS_ERROR_FAILURE;
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileReader::ReadFastID(NSFastLoadID *aID)
-{
-    nsresult rv = Read32(aID);
-    if (NS_SUCCEEDED(rv))
-        *aID ^= MFL_ID_XOR_KEY;
-    return rv;
-}
-
-nsresult
-nsFastLoadFileReader::ReadSharpObjectInfo(nsFastLoadSharpObjectInfo *aInfo)
-{
-    nsresult rv;
-
-    rv = Read32(&aInfo->mCIDOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    NS_ASSERTION(aInfo->mCIDOffset != 0,
-                 "fastload reader: mCIDOffset cannot be zero!");
-
-    rv = Read16(&aInfo->mStrongRefCnt);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Read16(&aInfo->mWeakRefCnt);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileReader::ReadMuxedDocumentInfo(nsFastLoadMuxedDocumentInfo *aInfo)
-{
-    nsresult rv;
-
-    nsCAutoString spec;
-    rv = ReadCString(spec);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Read32(&aInfo->mInitialSegmentOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    aInfo->mURISpec = ToNewCString(spec);
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileReader::Open()
-{
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mInputStream));
-    if (!seekable)
-        return NS_ERROR_UNEXPECTED;
-
-    nsresult rv;
-
-    // Don't bother buffering the header, as we immediately seek to EOF.
-    nsCOMPtr<nsIStreamBufferAccess>
-        bufferAccess(do_QueryInterface(mInputStream));
-    if (bufferAccess)
-        bufferAccess->DisableBuffering();
-
-    rv = ReadHeader(&mHeader);
-
-    if (bufferAccess)
-        bufferAccess->EnableBuffering();
-    if (NS_FAILED(rv))
-        return rv;
-
-    if (mHeader.mVersion != MFL_FILE_VERSION)
-        return NS_ERROR_UNEXPECTED;
-    if (mHeader.mFooterOffset == 0)
-        return NS_ERROR_UNEXPECTED;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_END, 0);
-    if (NS_FAILED(rv))
-        return rv;
-
-    PRInt64 fileSize;
-    rv = seekable->Tell(&fileSize);
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsInt64 fileSize64 = fileSize;
-    const nsInt64 maxUint32 = PR_UINT32_MAX;
-    NS_ASSERTION(fileSize64 <= maxUint32, "fileSize must fit in 32 bits");
-    if ((PRUint32) fileSize64 != mHeader.mFileSize)
-        return NS_ERROR_UNEXPECTED;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                        PRInt32(mHeader.mFooterOffset));
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = ReadFooter(&mFooter);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                          sizeof(nsFastLoadHeader));
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::Close()
-{
-    // Give up our strong "keepalive" references, in case not all objects that
-    // were deserialized were fully re-connected.
-    //
-    // This happens for sure when an nsFastLoadFileUpdater is created and wraps
-    // an nsFastLoadFileReader whose data was already deserialized by an earlier
-    // FastLoad episode.  The reader is useful in the second such episode during
-    // a session not so much for reading objects as for its footer information,
-    // which primes the updater's tables so that after the update completes, the
-    // FastLoad file has a superset footer.
-
-    for (PRUint32 i = 0, n = mFooter.mNumSharpObjects; i < n; i++) {
-        nsObjectMapEntry* entry = &mFooter.mObjectMap[i];
-        entry->mReadObject = nsnull;
-    }
-
-    return mInputStream->Close();
-}
-
-nsresult
-nsFastLoadFileReader::DeserializeObject(nsISupports* *aObject)
-{
-    nsresult rv;
-    NSFastLoadID fastCID;
-
-    rv = ReadFastID(&fastCID);
-    if (NS_FAILED(rv))
-        return rv;
-
-    const nsID& slowCID = mFooter.GetID(fastCID);
-    nsCOMPtr<nsISupports> object(do_CreateInstance(slowCID, &rv));
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCOMPtr<nsISerializable> serializable(do_QueryInterface(object));
-    if (!serializable)
-        return NS_ERROR_FAILURE;
-
-    rv = serializable->Read(this);
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aObject = object;
-    NS_ADDREF(*aObject);
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileReader::ReadObject(PRBool aIsStrongRef, nsISupports* *aObject)
-{
-    nsresult rv;
-    NSFastLoadOID oid;
-
-    rv = Read32(&oid);
-    if (NS_FAILED(rv))
-        return rv;
-    oid ^= MFL_OID_XOR_KEY;
-
-    nsCOMPtr<nsISupports> object;
-
-    if (oid == MFL_DULL_OBJECT_OID) {
-        // A very dull object, defined at point of single (strong) reference.
-        NS_ASSERTION(aIsStrongRef, "dull object read via weak ref!");
-
-        rv = DeserializeObject(getter_AddRefs(object));
-        if (NS_FAILED(rv))
-            return rv;
-    } else {
-        NS_ASSERTION((oid & MFL_WEAK_REF_TAG) ==
-                     (aIsStrongRef ? 0 : MFL_WEAK_REF_TAG),
-                     "strong vs. weak ref deserialization mismatch!");
-
-        nsObjectMapEntry* entry = &mFooter.GetSharpObjectEntry(oid);
-
-        // Check whether we've already deserialized the object for this OID.
-        object = entry->mReadObject;
-        if (!object) {
-            nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mInputStream));
-            PRInt64 saveOffset;
-            nsDocumentMapReadEntry* saveDocMapEntry = nsnull;
-
-            rv = seekable->Tell(&saveOffset);
-            if (NS_FAILED(rv))
-                return rv;
-
-            PRUint32 saveOffset32 = saveOffset;
-            if (entry->mCIDOffset != saveOffset32) {
-                // We skipped deserialization of this object from its position
-                // earlier in the input stream, presumably due to the reference
-                // there being an nsFastLoadPtr, or (more likely) because the
-                // object was muxed in another document, and deserialization
-                // order does not match serialization order.  So we must seek
-                // back and read it now.
-                NS_ASSERTION(entry->mCIDOffset < saveOffset32,
-                             "out of order object?!");
-
-                // Ape our Seek wrapper by clearing mCurrentDocumentMapEntry.
-                // This allows for a skipped object to be referenced from two
-                // or more multiplexed documents in the FastLoad file.
-                saveDocMapEntry = mCurrentDocumentMapEntry;
-                mCurrentDocumentMapEntry = nsnull;
-                rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                                    entry->mCIDOffset);
-                if (NS_FAILED(rv))
-                    return rv;
-            }
-
-            rv = DeserializeObject(getter_AddRefs(object));
-            if (NS_FAILED(rv))
-                return rv;
-
-            if (entry->mCIDOffset != saveOffset32) {
-                // Save the "skip offset" in case we need to skip this object
-                // definition when reading forward, later on.
-                rv = seekable->Tell(&entry->mSkipOffset);
-                if (NS_FAILED(rv))
-                    return rv;
-
-                // Restore stream offset and mCurrentDocumentMapEntry in case
-                // we're still reading forward through a part of the multiplex
-                // to get object definitions eagerly.
-                rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, saveOffset);
-                if (NS_FAILED(rv))
-                    return rv;
-                mCurrentDocumentMapEntry = saveDocMapEntry;
-            }
-
-            // Save object until all refs have been deserialized.
-            entry->mReadObject = object;
-        } else {
-            // What if we are at a definition that's already been read?  This
-            // case arises when a sharp object's def is serialized before its
-            // refs, while a non-defining ref is deserialized before the def.
-            // We must skip over the object definition.
-            if (oid & MFL_OBJECT_DEF_TAG) {
-                NS_ASSERTION(entry->mSkipOffset != 0, "impossible! see above");
-                nsCOMPtr<nsISeekableStream>
-                    seekable(do_QueryInterface(mInputStream));
-                rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                                    entry->mSkipOffset);
-                if (NS_FAILED(rv))
-                    return rv;
-            }
-        }
-
-        if (aIsStrongRef) {
-            NS_ASSERTION(entry->mStrongRefCnt != 0,
-                         "mStrongRefCnt underflow!");
-            --entry->mStrongRefCnt;
-        } else {
-            NS_ASSERTION(MFL_GET_WEAK_REFCNT(entry) != 0,
-                         "mWeakRefCnt underflow!");
-            MFL_DROP_WEAK_REFCNT(entry);
-        }
-
-        if (entry->mStrongRefCnt == 0 && MFL_GET_WEAK_REFCNT(entry) == 0)
-            entry->mReadObject = nsnull;
-    }
-
-    if (oid & MFL_QUERY_INTERFACE_TAG) {
-        NSFastLoadID iid;
-        rv = ReadFastID(&iid);
-        if (NS_FAILED(rv))
-            return rv;
-
-        rv = object->QueryInterface(mFooter.GetID(iid),
-                                    NS_REINTERPRET_CAST(void**, aObject));
-        if (NS_FAILED(rv))
-            return rv;
-    } else {
-        *aObject = object;
-        NS_ADDREF(*aObject);
-    }
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::ReadID(nsID *aResult)
-{
-    nsresult rv;
-    NSFastLoadID fastID;
-
-    rv = ReadFastID(&fastID);
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aResult = mFooter.GetID(fastID);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::Seek(PRInt32 aWhence, PRInt64 aOffset)
-{
-    mCurrentDocumentMapEntry = nsnull;
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mInputStream));
-    return seekable->Seek(aWhence, aOffset);
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::Tell(PRInt64 *aResult)
-{
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mInputStream));
-    return seekable->Tell(aResult);
-}
-
-NS_IMETHODIMP
-nsFastLoadFileReader::SetEOF()
-{
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mInputStream));
-    return seekable->SetEOF();
-}
-
-NS_COM nsresult
-NS_NewFastLoadFileReader(nsIObjectInputStream* *aResult,
-                         nsIInputStream* aSrcStream)
-{
-    nsFastLoadFileReader* reader = new nsFastLoadFileReader(aSrcStream);
-    if (!reader)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    // Stabilize reader's refcnt.
-    nsCOMPtr<nsIObjectInputStream> stream(reader);
-
-    nsresult rv = reader->Open();
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aResult = stream;
-    NS_ADDREF(*aResult);
-    return NS_OK;
-}
-
-// -------------------------- nsFastLoadFileWriter --------------------------
-
-NS_IMPL_ISUPPORTS_INHERITED4(nsFastLoadFileWriter,
-                             nsBinaryOutputStream,
-                             nsIObjectOutputStream,
-                             nsIFastLoadFileControl,
-                             nsIFastLoadWriteControl,
-                             nsISeekableStream)
-
-MOZ_DECL_CTOR_COUNTER(nsFastLoadFileWriter)
-
-struct nsIDMapEntry : public PLDHashEntryHdr {
-    NSFastLoadID    mFastID;            // 1 + nsFastLoadFooter::mIDMap index
-    nsID            mSlowID;            // key, used by PLDHashTableOps below
-};
-
-PR_STATIC_CALLBACK(const void *)
-idmap_GetKey(PLDHashTable *aTable, PLDHashEntryHdr *aHdr)
-{
-    nsIDMapEntry* entry = NS_STATIC_CAST(nsIDMapEntry*, aHdr);
-
-    return &entry->mSlowID;
-}
-
-PR_STATIC_CALLBACK(PLDHashNumber)
-idmap_HashKey(PLDHashTable *aTable, const void *aKey)
-{
-    const nsID *idp = NS_REINTERPRET_CAST(const nsID*, aKey);
-
-    return idp->m0;
-}
-
-PR_STATIC_CALLBACK(PRBool)
-idmap_MatchEntry(PLDHashTable *aTable,
-                const PLDHashEntryHdr *aHdr,
-                const void *aKey)
-{
-    const nsIDMapEntry* entry = NS_STATIC_CAST(const nsIDMapEntry*, aHdr);
-    const nsID *idp = NS_REINTERPRET_CAST(const nsID*, aKey);
-
-    return memcmp(&entry->mSlowID, idp, sizeof(nsID)) == 0;
-}
-
-static const PLDHashTableOps idmap_DHashTableOps = {
-    PL_DHashAllocTable,
-    PL_DHashFreeTable,
-    idmap_GetKey,
-    idmap_HashKey,
-    idmap_MatchEntry,
-    PL_DHashMoveEntryStub,
-    PL_DHashClearEntryStub,
-    PL_DHashFinalizeStub,
-    NULL
-};
-
-nsresult
-nsFastLoadFileWriter::MapID(const nsID& aSlowID, NSFastLoadID *aResult)
-{
-    nsIDMapEntry* entry =
-        NS_STATIC_CAST(nsIDMapEntry*,
-                       PL_DHashTableOperate(&mIDMap, &aSlowID, PL_DHASH_ADD));
-    if (!entry)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    if (entry->mFastID == 0) {
-        entry->mFastID = mIDMap.entryCount;
-        entry->mSlowID = aSlowID;
-    }
-
-    *aResult = entry->mFastID;
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileWriter::WriteHeader(nsFastLoadHeader *aHeader)
-{
-    nsresult rv;
-    PRUint32 bytesWritten;
-
-    rv = Write(aHeader->mMagic, MFL_FILE_MAGIC_SIZE, &bytesWritten);
-    if (NS_FAILED(rv))
-        return rv;
-
-    if (bytesWritten != MFL_FILE_MAGIC_SIZE)
-        return NS_ERROR_FAILURE;
-
-    rv = Write32(aHeader->mChecksum);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(aHeader->mVersion);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(aHeader->mFooterOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(aHeader->mFileSize);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return NS_OK;
-}
-
-// nsIFastLoadFileControl methods:
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::GetChecksum(PRUint32 *aChecksum)
-{
-    if (mHeader.mChecksum == 0)
-        return NS_ERROR_NOT_AVAILABLE;
-    *aChecksum = mHeader.mChecksum;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::SetChecksum(PRUint32 aChecksum)
-{
-    mHeader.mChecksum = aChecksum;
-    return NS_OK;
-}
-
-struct nsDocumentMapWriteEntry : public nsDocumentMapEntry {
-    PRUint32    mCurrentSegmentOffset;      // last written segment's offset
-};
-
-// Fast mapping from URI object pointer back to spec-indexed document info.
-// We also may need the slow mapping from mURISpec to nsDocumentMapWriteEntry,
-// because the writer's mDocumentMap double hash table may grow "behind the
-// back of" each mURIMap entry's mDocMapEntry member.
-struct nsURIMapWriteEntry : public nsObjectMapEntry {
-    nsDocumentMapWriteEntry* mDocMapEntry;
-    PRUint32                 mGeneration;
-    const char*              mURISpec;
-};
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::HasMuxedDocument(const char* aURISpec, PRBool *aResult)
-{
-    nsDocumentMapWriteEntry* docMapEntry =
-        NS_STATIC_CAST(nsDocumentMapWriteEntry*,
-                       PL_DHashTableOperate(&mDocumentMap, aURISpec,
-                                            PL_DHASH_LOOKUP));
-
-    *aResult = PL_DHASH_ENTRY_IS_BUSY(docMapEntry);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::StartMuxedDocument(nsISupports* aURI,
-                                         const char* aURISpec)
-{
-    // Save mDocumentMap table generation and mCurrentDocumentMapEntry key in
-    // case the hash table grows during the PL_DHASH_ADD operation.
-    PRUint32 saveGeneration = mDocumentMap.generation;
-    const char* saveURISpec = mCurrentDocumentMapEntry
-                              ? mCurrentDocumentMapEntry->mString
-                              : nsnull;
-
-    nsDocumentMapWriteEntry* docMapEntry =
-        NS_STATIC_CAST(nsDocumentMapWriteEntry*,
-                       PL_DHashTableOperate(&mDocumentMap, aURISpec,
-                                            PL_DHASH_ADD));
-    if (!docMapEntry)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    // If the generation number changed, refresh mCurrentDocumentMapEntry.
-    if (mCurrentDocumentMapEntry && mDocumentMap.generation != saveGeneration) {
-        mCurrentDocumentMapEntry =
-            NS_STATIC_CAST(nsDocumentMapWriteEntry*,
-                           PL_DHashTableOperate(&mDocumentMap, saveURISpec,
-                                                PL_DHASH_LOOKUP));
-        NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(mCurrentDocumentMapEntry),
-                     "mCurrentDocumentMapEntry lost during table growth?!");
-
-        // Refresh saveGeneration for use below when initializing uriMapEntry.
-        saveGeneration = mDocumentMap.generation;
-    }
-
-    NS_ASSERTION(docMapEntry->mString == nsnull,
-                 "redundant multiplexed document?");
-    if (docMapEntry->mString)
-        return NS_ERROR_UNEXPECTED;
-
-    void* spec = nsMemory::Clone(aURISpec, strlen(aURISpec) + 1);
-    if (!spec)
-        return NS_ERROR_OUT_OF_MEMORY;
-    docMapEntry->mString = NS_REINTERPRET_CAST(const char*, spec);
-    docMapEntry->mURI = aURI;
-    NS_ADDREF(docMapEntry->mURI);
-
-    nsCOMPtr<nsISupports> key(do_QueryInterface(aURI));
-    nsURIMapWriteEntry* uriMapEntry =
-        NS_STATIC_CAST(nsURIMapWriteEntry*,
-                       PL_DHashTableOperate(&mURIMap, key, PL_DHASH_ADD));
-    if (!uriMapEntry)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    NS_ASSERTION(uriMapEntry->mDocMapEntry == nsnull,
-                 "URI mapped to two different specs?");
-    if (uriMapEntry->mDocMapEntry)
-        return NS_ERROR_UNEXPECTED;
-
-    uriMapEntry->mObject = key;
-    NS_ADDREF(uriMapEntry->mObject);
-    uriMapEntry->mDocMapEntry = docMapEntry;
-    uriMapEntry->mGeneration = saveGeneration;
-    uriMapEntry->mURISpec = NS_REINTERPRET_CAST(const char*, spec);
-    TRACE_MUX(('w', "start %p (%p) %s\n", aURI, key.get(), aURISpec));
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::SelectMuxedDocument(nsISupports* aURI,
-                                          nsISupports** aResult)
-{
-    // Avoid repeatedly QI'ing to nsISeekableStream as we tell and seek.
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mOutputStream));
-
-    // Capture the current file offset (XXXbe maintain our own via Write?)
-    nsresult rv;
-    PRInt64 currentSegmentOffset;
-    rv = seekable->Tell(&currentSegmentOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    PRUint32 currentSegmentOffset32 = currentSegmentOffset;
-    // Look for an existing entry keyed by aURI, added by StartMuxedDocument.
-    nsCOMPtr<nsISupports> key(do_QueryInterface(aURI));
-    nsURIMapWriteEntry* uriMapEntry =
-        NS_STATIC_CAST(nsURIMapWriteEntry*,
-                       PL_DHashTableOperate(&mURIMap, key, PL_DHASH_LOOKUP));
-    NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(uriMapEntry),
-                 "SelectMuxedDocument without prior StartMuxedDocument?");
-    if (PL_DHASH_ENTRY_IS_FREE(uriMapEntry))
-        return NS_ERROR_UNEXPECTED;
-
-    // Beware that uriMapEntry->mDocMapEntry may be stale, if an mDocumentMap
-    // addition caused that table to grow.  We save the mDocumentMap generation
-    // in each uriMapEntry and compare it to the current generation, rehashing
-    // uriMapEntry->mURISpec if necessary.
-
-    nsDocumentMapWriteEntry* docMapEntry = uriMapEntry->mDocMapEntry;
-    if (uriMapEntry->mGeneration != mDocumentMap.generation) {
-        docMapEntry =
-            NS_STATIC_CAST(nsDocumentMapWriteEntry*,
-                           PL_DHashTableOperate(&mDocumentMap,
-                                                uriMapEntry->mURISpec,
-                                                PL_DHASH_LOOKUP));
-        NS_ASSERTION(PL_DHASH_ENTRY_IS_BUSY(docMapEntry), "lost mDocMapEntry!?");
-        uriMapEntry->mDocMapEntry = docMapEntry;
-        uriMapEntry->mGeneration = mDocumentMap.generation;
-    }
-    docMapEntry = uriMapEntry->mDocMapEntry;
-
-    // If there is a muxed document segment open, close it now by setting its
-    // length, stored in the second PRUint32 of the segment.
-    nsDocumentMapWriteEntry* prevDocMapEntry = mCurrentDocumentMapEntry;
-    if (prevDocMapEntry) {
-        if (prevDocMapEntry == docMapEntry) {
-            TRACE_MUX(('w', "select prev %s same as current!\n",
-                       prevDocMapEntry->mString));
-            *aResult = docMapEntry->mURI;
-            NS_ADDREF(*aResult);
-            return NS_OK;
-        }
-
-        PRUint32 prevSegmentOffset = prevDocMapEntry->mCurrentSegmentOffset;
-        TRACE_MUX(('w', "select prev %s offset %lu\n",
-                   prevDocMapEntry->mString, prevSegmentOffset));
-
-        rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                            prevSegmentOffset + 4);
-        if (NS_FAILED(rv))
-            return rv;
-
-        // The length counts all bytes in the segment, including the header
-        // that contains [nextSegmentOffset, length].
-        rv = Write32(currentSegmentOffset32 - prevSegmentOffset);
-        if (NS_FAILED(rv))
-            return rv;
-
-        // Seek back to the current offset only if we are not going to seek
-        // back to *this* entry's last "current" segment offset and write its
-        // next segment offset at the first PRUint32 of the segment.
-        if (!docMapEntry->mInitialSegmentOffset) {
-            rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                                currentSegmentOffset);
-            if (NS_FAILED(rv))
-                return rv;
-        }
-    }
-
-    // If this entry was newly added, set its key and initial segment offset.
-    // Otherwise, seek back to write the next segment offset of the previous
-    // segment for this document in the multiplex.
-    if (!docMapEntry->mInitialSegmentOffset) {
-        docMapEntry->mInitialSegmentOffset = currentSegmentOffset32;
-    } else {
-        rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                            docMapEntry->mCurrentSegmentOffset);
-        if (NS_FAILED(rv))
-            return rv;
-
-        rv = Write32(currentSegmentOffset32);
-        if (NS_FAILED(rv))
-            return rv;
-
-        rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                            currentSegmentOffset);
-        if (NS_FAILED(rv))
-            return rv;
-    }
-
-    // Update this document's current segment offset so we can later fix its
-    // next segment offset (unless it is last, in which case we leave the zero
-    // placeholder as a terminator).
-    docMapEntry->mCurrentSegmentOffset = currentSegmentOffset32;
-
-    rv = Write32(0);    // nextSegmentOffset placeholder
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(0);    // length placeholder
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aResult = prevDocMapEntry ? prevDocMapEntry->mURI : nsnull;
-    NS_IF_ADDREF(*aResult);
-
-    mCurrentDocumentMapEntry = docMapEntry;
-    TRACE_MUX(('w', "select %p (%p) offset %lu\n",
-               aURI, key.get(), currentSegmentOffset));
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::EndMuxedDocument(nsISupports* aURI)
-{
-    nsCOMPtr<nsISupports> key(do_QueryInterface(aURI));
-    nsURIMapWriteEntry* uriMapEntry =
-        NS_STATIC_CAST(nsURIMapWriteEntry*,
-                       PL_DHashTableOperate(&mURIMap, key, PL_DHASH_LOOKUP));
-
-    // If the URI isn't in the map, nsFastLoadFileWriter::StartMuxedDocument
-    // must have been called with a redundant URI, *and* its caller must have
-    // ignored the NS_ERROR_UNEXPECTED it returned in that case.
-    if (PL_DHASH_ENTRY_IS_FREE(uriMapEntry)) {
-        TRACE_MUX(('w', "bad end %p (%p)\n", aURI, key.get()));
-        return NS_ERROR_UNEXPECTED;
-    }
-
-    // Drop our ref to the URI object that was passed to StartMuxedDocument,
-    // we no longer need it, and we do not want to extend its lifetime.
-    if (uriMapEntry->mDocMapEntry)
-        NS_RELEASE(uriMapEntry->mDocMapEntry->mURI);
-
-    // Shrink the table if half the entries are removed sentinels.
-    PRUint32 size = PL_DHASH_TABLE_SIZE(&mURIMap);
-    if (mURIMap.removedCount >= (size >> 2))
-        PL_DHashTableOperate(&mURIMap, key, PL_DHASH_REMOVE);
-    else
-        PL_DHashTableRawRemove(&mURIMap, uriMapEntry);
-
-    TRACE_MUX(('w', "end %p (%p)\n", aURI, key.get()));
-    return NS_OK;
-}
-
-struct nsDependencyMapEntry : public nsStringMapEntry {
-    PRInt64 mLastModified;
-};
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::AddDependency(nsIFile* aFile)
-{
-    nsCAutoString path;
-    nsresult rv = aFile->GetNativePath(path);
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsDependencyMapEntry* entry =
-        NS_STATIC_CAST(nsDependencyMapEntry*,
-                       PL_DHashTableOperate(&mDependencyMap, path.get(),
-                                            PL_DHASH_ADD));
-    if (!entry)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    if (!entry->mString) {
-        const char *tmp = ToNewCString(path);
-        if (!tmp)
-            return NS_ERROR_OUT_OF_MEMORY;
-        entry->mString = tmp;
-
-        // If we can't get the last modified time from aFile, assume it does
-        // not exist, or is otherwise inaccessible to us (due to permissions),
-        // remove the dependency, and suppress the failure.
-        //
-        // Otherwise, we would end up aborting the fastload process due to a
-        // missing .js or .xul or other file on every startup.
-
-        rv = aFile->GetLastModifiedTime(&entry->mLastModified);
-        if (NS_FAILED(rv)) {
-            PL_DHashTableOperate(&mDependencyMap, path.get(), PL_DHASH_REMOVE);
-            rv = NS_OK;
-        }
-    }
-    return rv;
-}
-
-nsresult
-nsFastLoadFileWriter::WriteFooterPrefix(const nsFastLoadFooterPrefix& aFooterPrefix)
-{
-    nsresult rv;
-
-    rv = Write32(aFooterPrefix.mNumIDs);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(aFooterPrefix.mNumSharpObjects);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(aFooterPrefix.mNumMuxedDocuments);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(aFooterPrefix.mNumDependencies);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileWriter::WriteSlowID(const nsID& aID)
-{
-    nsresult rv;
-
-    rv = Write32(aID.m0);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write16(aID.m1);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write16(aID.m2);
-    if (NS_FAILED(rv))
-        return rv;
-
-    PRUint32 bytesWritten;
-    rv = Write(NS_REINTERPRET_CAST(const char*, aID.m3), sizeof aID.m3,
-               &bytesWritten);
-    if (NS_FAILED(rv))
-        return rv;
-
-    if (bytesWritten != sizeof aID.m3)
-        return NS_ERROR_FAILURE;
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileWriter::WriteFastID(NSFastLoadID aID)
-{
-    return Write32(aID ^ MFL_ID_XOR_KEY);
-}
-
-nsresult
-nsFastLoadFileWriter::WriteSharpObjectInfo(const nsFastLoadSharpObjectInfo& aInfo)
-{
-    nsresult rv;
-
-    NS_ASSERTION(aInfo.mCIDOffset != 0,
-                 "fastload writer: mCIDOffset cannot be zero!");
-
-    rv = Write32(aInfo.mCIDOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write16(aInfo.mStrongRefCnt);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write16(aInfo.mWeakRefCnt);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileWriter::WriteMuxedDocumentInfo(const nsFastLoadMuxedDocumentInfo& aInfo)
-{
-    nsresult rv;
-
-    rv = WriteStringZ(aInfo.mURISpec);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(aInfo.mInitialSegmentOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return NS_OK;
-}
-
-PLDHashOperator PR_CALLBACK
-nsFastLoadFileWriter::IDMapEnumerate(PLDHashTable *aTable,
-                                     PLDHashEntryHdr *aHdr,
-                                     PRUint32 aNumber,
-                                     void *aData)
-{
-    nsIDMapEntry* entry = NS_STATIC_CAST(nsIDMapEntry*, aHdr);
-    PRUint32 index = entry->mFastID - 1;
-    nsID* vector = NS_REINTERPRET_CAST(nsID*, aData);
-
-    NS_ASSERTION(index < aTable->entryCount, "bad nsIDMap index!");
-    vector[index] = entry->mSlowID;
-    return PL_DHASH_NEXT;
-}
-
-struct nsSharpObjectMapEntry : public nsObjectMapEntry {
-    NSFastLoadOID               mOID;
-    nsFastLoadSharpObjectInfo   mInfo;
-};
-
-PLDHashOperator PR_CALLBACK
-nsFastLoadFileWriter::ObjectMapEnumerate(PLDHashTable *aTable,
-                                         PLDHashEntryHdr *aHdr,
-                                         PRUint32 aNumber,
-                                         void *aData)
-{
-    nsSharpObjectMapEntry* entry = NS_STATIC_CAST(nsSharpObjectMapEntry*, aHdr);
-    PRUint32 index = MFL_OID_TO_SHARP_INDEX(entry->mOID);
-    nsFastLoadSharpObjectInfo* vector =
-        NS_REINTERPRET_CAST(nsFastLoadSharpObjectInfo*, aData);
-
-    NS_ASSERTION(index < aTable->entryCount, "bad nsObjectMap index!");
-    vector[index] = entry->mInfo;
-
-    NS_ASSERTION(entry->mInfo.mStrongRefCnt, "no strong ref in serialization!");
-
-    // Ignore tagged object ids stored as object pointer keys (the updater
-    // code does this).
-    if ((NS_PTR_TO_INT32(entry->mObject) & MFL_OBJECT_DEF_TAG) == 0)
-        NS_RELEASE(entry->mObject);
-
-    return PL_DHASH_NEXT;
-}
-
-PLDHashOperator PR_CALLBACK
-nsFastLoadFileWriter::DocumentMapEnumerate(PLDHashTable *aTable,
-                                           PLDHashEntryHdr *aHdr,
-                                           PRUint32 aNumber,
-                                           void *aData)
-{
-    nsFastLoadFileWriter* writer =
-        NS_REINTERPRET_CAST(nsFastLoadFileWriter*, aTable->data);
-    nsDocumentMapWriteEntry* entry =
-        NS_STATIC_CAST(nsDocumentMapWriteEntry*, aHdr);
-    nsresult* rvp = NS_REINTERPRET_CAST(nsresult*, aData);
-
-    nsFastLoadMuxedDocumentInfo info;
-    info.mURISpec = entry->mString;
-    info.mInitialSegmentOffset = entry->mInitialSegmentOffset;
-    *rvp = writer->WriteMuxedDocumentInfo(info);
-
-    return NS_FAILED(*rvp) ? PL_DHASH_STOP : PL_DHASH_NEXT;
-}
-
-PLDHashOperator PR_CALLBACK
-nsFastLoadFileWriter::DependencyMapEnumerate(PLDHashTable *aTable,
-                                             PLDHashEntryHdr *aHdr,
-                                             PRUint32 aNumber,
-                                             void *aData)
-{
-    nsFastLoadFileWriter* writer =
-        NS_REINTERPRET_CAST(nsFastLoadFileWriter*, aTable->data);
-    nsDependencyMapEntry* entry = NS_STATIC_CAST(nsDependencyMapEntry*, aHdr);
-    nsresult* rvp = NS_REINTERPRET_CAST(nsresult*, aData);
-
-    *rvp = writer->WriteStringZ(entry->mString);
-    if (NS_SUCCEEDED(*rvp))
-        *rvp = writer->Write64(entry->mLastModified);
-
-    return NS_FAILED(*rvp) ? PL_DHASH_STOP :PL_DHASH_NEXT;
-}
-
-nsresult
-nsFastLoadFileWriter::WriteFooter()
-{
-    nsresult rv;
-    PRUint32 i, count;
-
-    nsFastLoadFooterPrefix footerPrefix;
-    footerPrefix.mNumIDs = mIDMap.entryCount;
-    footerPrefix.mNumSharpObjects = mObjectMap.entryCount;
-    footerPrefix.mNumMuxedDocuments = mDocumentMap.entryCount;
-    footerPrefix.mNumDependencies = mDependencyMap.entryCount;
-
-    rv = WriteFooterPrefix(footerPrefix);
-    if (NS_FAILED(rv))
-        return rv;
-
-    // Enumerate mIDMap into a vector indexed by mFastID and write it.
-    nsID* idvec = new nsID[footerPrefix.mNumIDs];
-    if (!idvec)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    count = PL_DHashTableEnumerate(&mIDMap, IDMapEnumerate, idvec);
-    NS_ASSERTION(count == footerPrefix.mNumIDs, "bad mIDMap enumeration!");
-    for (i = 0; i < count; i++) {
-        rv = WriteSlowID(idvec[i]);
-        if (NS_FAILED(rv)) break;
-    }
-
-    delete[] idvec;
-    if (NS_FAILED(rv))
-        return rv;
-
-    // Enumerate mObjectMap into a vector indexed by mOID and write it.
-    nsFastLoadSharpObjectInfo* objvec =
-        new nsFastLoadSharpObjectInfo[footerPrefix.mNumSharpObjects];
-    if (!objvec)
-        return NS_ERROR_OUT_OF_MEMORY;
-#ifdef NS_DEBUG
-    memset(objvec, 0, footerPrefix.mNumSharpObjects *
-                      sizeof(nsFastLoadSharpObjectInfo));
-#endif
-
-    count = PL_DHashTableEnumerate(&mObjectMap, ObjectMapEnumerate, objvec);
-    NS_ASSERTION(count == footerPrefix.mNumSharpObjects,
-                 "bad mObjectMap enumeration!");
-    for (i = 0; i < count; i++) {
-        rv = WriteSharpObjectInfo(objvec[i]);
-        if (NS_FAILED(rv)) break;
-    }
-
-    delete[] objvec;
-    if (NS_FAILED(rv))
-        return rv;
-
-    // Enumerate mDocumentMap, writing nsFastLoadMuxedDocumentInfo records
-    count = PL_DHashTableEnumerate(&mDocumentMap, DocumentMapEnumerate, &rv);
-    if (NS_FAILED(rv))
-        return rv;
-
-    NS_ASSERTION(count == footerPrefix.mNumMuxedDocuments,
-                 "bad mDocumentMap enumeration!");
-
-    // Write out make-like file dependencies.
-    count = PL_DHashTableEnumerate(&mDependencyMap, DependencyMapEnumerate, &rv);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileWriter::Init()
-{
-    if (!PL_DHashTableInit(&mIDMap, &idmap_DHashTableOps, (void *)this,
-                           sizeof(nsIDMapEntry), PL_DHASH_MIN_SIZE)) {
-        mIDMap.ops = nsnull;
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    if (!PL_DHashTableInit(&mObjectMap, &objmap_DHashTableOps, (void *)this,
-                           sizeof(nsSharpObjectMapEntry), PL_DHASH_MIN_SIZE)) {
-        mObjectMap.ops = nsnull;
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    if (!PL_DHashTableInit(&mDocumentMap, &strmap_DHashTableOps, (void *)this,
-                           sizeof(nsDocumentMapWriteEntry),
-                           PL_DHASH_MIN_SIZE)) {
-        mDocumentMap.ops = nsnull;
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    if (!PL_DHashTableInit(&mURIMap, &objmap_DHashTableOps, (void *)this,
-                           sizeof(nsURIMapWriteEntry), PL_DHASH_MIN_SIZE)) {
-        mURIMap.ops = nsnull;
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    if (!PL_DHashTableInit(&mDependencyMap, &strmap_DHashTableOps, (void *)this,
-                           sizeof(nsDependencyMapEntry), PL_DHASH_MIN_SIZE)) {
-        mDependencyMap.ops = nsnull;
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    return NS_OK;
-}
-
-nsresult
-nsFastLoadFileWriter::Open()
-{
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mOutputStream));
-    if (!seekable)
-        return NS_ERROR_UNEXPECTED;
-
-    nsresult rv;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                        sizeof(nsFastLoadHeader));
-    if (NS_FAILED(rv))
-        return rv;
-
-    return Init();
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::Close()
-{
-    nsresult rv;
-
-    memcpy(mHeader.mMagic, magic, MFL_FILE_MAGIC_SIZE);
-    mHeader.mChecksum = 0;
-    mHeader.mVersion = MFL_FILE_VERSION;
-
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mOutputStream));
-
-    PRInt64 footerOffset;
-    rv = seekable->Tell(&footerOffset);
-
-    LL_L2UI(mHeader.mFooterOffset, footerOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    // If there is a muxed document segment open, close it now by setting its
-    // length, stored in the second PRUint32 of the segment.
-    if (mCurrentDocumentMapEntry) {
-        PRUint32 currentSegmentOffset =
-            mCurrentDocumentMapEntry->mCurrentSegmentOffset;
-        rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                            currentSegmentOffset + 4);
-        if (NS_FAILED(rv))
-            return rv;
-
-        rv = Write32(mHeader.mFooterOffset - currentSegmentOffset);
-        if (NS_FAILED(rv))
-            return rv;
-
-        // Seek back to the current offset to write the footer.
-        rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                            mHeader.mFooterOffset);
-        if (NS_FAILED(rv))
-            return rv;
-
-        mCurrentDocumentMapEntry = nsnull;
-    }
-
-    rv = WriteFooter();
-    if (NS_FAILED(rv))
-        return rv;
-    PRInt64 fileSize;
-    rv = seekable->Tell(&fileSize);
-    LL_L2UI(mHeader.mFileSize, fileSize);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = WriteHeader(&mHeader);
-    if (NS_FAILED(rv))
-        return rv;
-
-    // Now compute the checksum, using mFileIO to get an input stream on the
-    // underlying FastLoad file.
-    if (mFileIO) {
-        // Get the unbuffered output stream, which flushes the buffered header
-        // so we can read and checksum it along with the rest of the file, and
-        // which allows us to write the checksum directly.
-        nsCOMPtr<nsIStreamBufferAccess>
-            bufferAccess(do_QueryInterface(mOutputStream));
-        nsCOMPtr<nsIOutputStream> output;
-        rv = bufferAccess->GetUnbufferedStream(getter_AddRefs(output));
-        if (NS_FAILED(rv) || !output)
-            return NS_ERROR_UNEXPECTED;
-
-        nsCOMPtr<nsIInputStream> input;
-        rv = mFileIO->GetInputStream(getter_AddRefs(input));
-        if (NS_FAILED(rv))
-            return rv;
-
-        // Get the unbuffered input stream, to avoid copying overhead and to
-        // keep our view of the file coherent with the writer -- we don't want
-        // to hit a stale buffer in the reader's underlying stream.
-        bufferAccess = do_QueryInterface(input);
-        rv = bufferAccess->GetUnbufferedStream(getter_AddRefs(input));
-        if (NS_FAILED(rv) || !input)
-            return NS_ERROR_UNEXPECTED;
-
-        // Seek the input stream to offset 0, in case it's a reader who has
-        // already been used to consume some of the FastLoad file.
-        seekable = do_QueryInterface(input);
-        rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
-        if (NS_FAILED(rv))
-            return rv;
-
-        char buf[MFL_CHECKSUM_BUFSIZE];
-        PRUint32 len, rem = 0;
-        PRUint32 checksum = 0;
-
-        // Ok, we're finally ready to checksum the FastLoad file we just wrote!
-        while (NS_SUCCEEDED(rv =
-                            input->Read(buf + rem, sizeof buf - rem, &len)) &&
-               len) {
-            len += rem;
-            rem = NS_AccumulateFastLoadChecksum(&checksum,
-                                                NS_REINTERPRET_CAST(PRUint8*,
-                                                                    buf),
-                                                len,
-                                                PR_FALSE);
-            if (rem)
-                memcpy(buf, buf + len - rem, rem);
-        }
-        if (NS_FAILED(rv))
-            return rv;
-
-        if (rem) {
-            NS_AccumulateFastLoadChecksum(&checksum,
-                                          NS_REINTERPRET_CAST(PRUint8*, buf),
-                                          rem,
-                                          PR_TRUE);
-        }
-
-        // Store the checksum in the FastLoad file header and remember it via
-        // mHeader.mChecksum, for GetChecksum.
-        seekable = do_QueryInterface(output);
-        rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                            offsetof(nsFastLoadHeader, mChecksum));
-        if (NS_FAILED(rv))
-            return rv;
-
-        mHeader.mChecksum = checksum;
-        checksum = NS_SWAP32(checksum);
-        PRUint32 bytesWritten;
-        rv = output->Write(NS_REINTERPRET_CAST(char*, &checksum),
-                           sizeof checksum,
-                           &bytesWritten);
-        if (NS_FAILED(rv))
-            return rv;
-        if (bytesWritten != sizeof checksum)
-            return NS_ERROR_FAILURE;
-    }
-
-    return mOutputStream->Close();
-}
-
-// Psuedo-tag used as flag between WriteSingleRefObject and WriteObjectCommon.
-#define MFL_SINGLE_REF_PSEUDO_TAG       PR_BIT(MFL_OBJECT_TAG_BITS)
-
-nsresult
-nsFastLoadFileWriter::WriteObjectCommon(nsISupports* aObject,
-                                        PRBool aIsStrongRef,
-                                        PRUint32 aTags)
-{
-    nsrefcnt rc;
-    nsresult rv;
-
-    NS_ASSERTION((NS_PTR_TO_INT32(aObject) & MFL_OBJECT_DEF_TAG) == 0,
-                 "odd nsISupports*, oh no!");
-
-    // Here be manual refcounting dragons!
-    rc = aObject->AddRef();
-    NS_ASSERTION(rc != 0, "bad refcnt when writing aObject!");
-
-    NSFastLoadOID oid;
-    nsCOMPtr<nsIClassInfo> classInfo;
-
-    if (rc == 2 && (aTags & MFL_SINGLE_REF_PSEUDO_TAG)) {
-        // Dull object: only one strong ref and no weak refs in serialization.
-        // Conservative: we don't trust the caller if there are more than two
-        // refs (one from the AddRef above, one from the data structure that's
-        // being serialized).
-        oid = MFL_DULL_OBJECT_OID;
-        aObject->Release();
-    } else {
-        // Object is presumed to be multiply connected through some combo of
-        // strong and weak refs.  Hold onto it via mObjectMap.
-        nsSharpObjectMapEntry* entry =
-            NS_STATIC_CAST(nsSharpObjectMapEntry*,
-                           PL_DHashTableOperate(&mObjectMap, aObject,
-                                                PL_DHASH_ADD));
-        if (!entry) {
-            aObject->Release();
-            return NS_ERROR_OUT_OF_MEMORY;
-        }
-
-        if (!entry->mObject) {
-            // First time we've seen this object address: add it to mObjectMap
-            // and serialize the object at the current stream offset.
-            PRInt64 thisOffset;
-            rv = Tell(&thisOffset);
-            if (NS_FAILED(rv)) {
-                aObject->Release();
-                return rv;
-            }
-
-            // NB: aObject was already held, and mObject is a raw nsISupports*.
-            entry->mObject = aObject;
-
-            oid = (mObjectMap.entryCount << MFL_OBJECT_TAG_BITS);
-            entry->mOID = oid;
-
-            // NB: the (32-bit, fast) CID and object data follow the OID.
-            entry->mInfo.mCIDOffset = thisOffset + sizeof(oid);
-            entry->mInfo.mStrongRefCnt = aIsStrongRef ? 1 : 0;
-            entry->mInfo.mWeakRefCnt   = aIsStrongRef ? 0 : 1;
-
-            // Record in oid the fact that we're defining this object in the
-            // stream, and get the object's class info here, so we can take
-            // note of singletons in order to avoid reserializing them when
-            // updating after reading.
-            oid |= MFL_OBJECT_DEF_TAG;
-            classInfo = do_QueryInterface(aObject);
-            if (!classInfo)
-                return NS_ERROR_FAILURE;
-
-            PRUint32 flags;
-            if (NS_SUCCEEDED(classInfo->GetFlags(&flags)) &&
-                (flags & nsIClassInfo::SINGLETON)) {
-                MFL_SET_SINGLETON_FLAG(&entry->mInfo);
-            }
-        } else {
-            // Already serialized, recover oid and update the desired refcnt.
-            oid = entry->mOID;
-            if (aIsStrongRef) {
-                ++entry->mInfo.mStrongRefCnt;
-                NS_ASSERTION(entry->mInfo.mStrongRefCnt != 0,
-                             "mStrongRefCnt overflow");
-            } else {
-                MFL_BUMP_WEAK_REFCNT(&entry->mInfo);
-                NS_ASSERTION(MFL_GET_WEAK_REFCNT(&entry->mInfo) != 0,
-                             "mWeakRefCnt overflow");
-            }
-
-            aObject->Release();
-        }
-    }
-
-    if (!aIsStrongRef)
-        oid |= MFL_WEAK_REF_TAG;
-    oid |= (aTags & MFL_QUERY_INTERFACE_TAG);
-
-    rv = Write32(oid ^ MFL_OID_XOR_KEY);
-    if (NS_FAILED(rv))
-        return rv;
-
-    if (oid & MFL_OBJECT_DEF_TAG) {
-        nsCOMPtr<nsISerializable> serializable(do_QueryInterface(aObject));
-        if (!serializable)
-            return NS_ERROR_FAILURE;
-
-        nsCID slowCID;
-        rv = classInfo->GetClassIDNoAlloc(&slowCID);
-        if (NS_FAILED(rv))
-            return rv;
-
-        NSFastLoadID fastCID;
-        rv = MapID(slowCID, &fastCID);
-        if (NS_FAILED(rv))
-            return rv;
-
-        rv = WriteFastID(fastCID);
-        if (NS_FAILED(rv))
-            return rv;
-
-        rv = serializable->Write(this);
-        if (NS_FAILED(rv))
-            return rv;
-    }
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::WriteObject(nsISupports* aObject, PRBool aIsStrongRef)
-{
-#ifdef NS_DEBUG
-    nsCOMPtr<nsISupports> rootObject(do_QueryInterface(aObject));
-
-    NS_ASSERTION(rootObject.get() == aObject,
-                 "bad call to WriteObject -- call WriteCompoundObject!");
-#endif
-
-    return WriteObjectCommon(aObject, aIsStrongRef, 0);
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::WriteSingleRefObject(nsISupports* aObject)
-{
-#ifdef NS_DEBUG
-    nsCOMPtr<nsISupports> rootObject(do_QueryInterface(aObject));
-
-    NS_ASSERTION(rootObject.get() == aObject,
-                 "bad call to WriteSingleRefObject -- call WriteCompoundObject!");
-#endif
-
-    return WriteObjectCommon(aObject, PR_TRUE, MFL_SINGLE_REF_PSEUDO_TAG);
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::WriteCompoundObject(nsISupports* aObject,
-                                          const nsIID& aIID,
-                                          PRBool aIsStrongRef)
-{
-    nsresult rv;
-    nsCOMPtr<nsISupports> rootObject(do_QueryInterface(aObject));
-
-#ifdef NS_DEBUG
-    nsCOMPtr<nsISupports> roundtrip;
-    rootObject->QueryInterface(aIID, getter_AddRefs(roundtrip));
-
-    NS_ASSERTION(rootObject.get() != aObject,
-                 "wasteful call to WriteCompoundObject -- call WriteObject!");
-    NS_ASSERTION(roundtrip.get() == aObject,
-                 "bad aggregation or multiple inheritance detected by call to "
-                 "WriteCompoundObject!");
-#endif
-
-    rv = WriteObjectCommon(rootObject, aIsStrongRef, MFL_QUERY_INTERFACE_TAG);
-    if (NS_FAILED(rv))
-        return rv;
-
-    NSFastLoadID iid;
-    rv = MapID(aIID, &iid);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return WriteFastID(iid);
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::WriteID(const nsID& aID)
-{
-    nsresult rv;
-    NSFastLoadID fastID;
-
-    rv = MapID(aID, &fastID);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return WriteFastID(fastID);
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::Seek(PRInt32 aWhence, PRInt64 aOffset)
-{
-    mCurrentDocumentMapEntry = nsnull;
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mOutputStream));
-    return seekable->Seek(aWhence, aOffset);
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::Tell(PRInt64 *aResult)
-{
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mOutputStream));
-    return seekable->Tell(aResult);
-}
-
-NS_IMETHODIMP
-nsFastLoadFileWriter::SetEOF()
-{
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mOutputStream));
-    return seekable->SetEOF();
-}
-
-NS_COM nsresult
-NS_NewFastLoadFileWriter(nsIObjectOutputStream* *aResult,
-                         nsIOutputStream* aDestStream,
-                         nsIFastLoadFileIO* aFileIO)
-{
-    nsFastLoadFileWriter* writer =
-        new nsFastLoadFileWriter(aDestStream, aFileIO);
-    if (!writer)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    // Stabilize writer's refcnt.
-    nsCOMPtr<nsIObjectOutputStream> stream(writer);
-
-    nsresult rv = writer->Open();
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aResult = stream;
-    NS_ADDREF(*aResult);
-    return NS_OK;
-}
-
-// -------------------------- nsFastLoadFileUpdater --------------------------
-
-NS_IMPL_ISUPPORTS_INHERITED1(nsFastLoadFileUpdater,
-                             nsFastLoadFileWriter,
-                             nsIFastLoadFileIO)
-
-NS_IMETHODIMP
-nsFastLoadFileUpdater::GetInputStream(nsIInputStream** aResult)
-{
-    *aResult = mInputStream;
-    NS_IF_ADDREF(*aResult);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileUpdater::GetOutputStream(nsIOutputStream** aResult)
-{
-    *aResult = nsnull;
-    return NS_OK;
-}
-
-PLDHashOperator PR_CALLBACK
-nsFastLoadFileUpdater::CopyReadDocumentMapEntryToUpdater(PLDHashTable *aTable,
-                                                         PLDHashEntryHdr *aHdr,
-                                                         PRUint32 aNumber,
-                                                         void *aData)
-{
-    nsDocumentMapReadEntry* readEntry =
-        NS_STATIC_CAST(nsDocumentMapReadEntry*, aHdr);
-    nsFastLoadFileUpdater* updater =
-        NS_REINTERPRET_CAST(nsFastLoadFileUpdater*, aData);
-
-    void* spec = nsMemory::Clone(readEntry->mString,
-                                 strlen(readEntry->mString) + 1);
-    if (!spec)
-        return PL_DHASH_STOP;
-
-    nsDocumentMapWriteEntry* writeEntry =
-        NS_STATIC_CAST(nsDocumentMapWriteEntry*,
-                       PL_DHashTableOperate(&updater->mDocumentMap, spec,
-                                            PL_DHASH_ADD));
-    if (!writeEntry) {
-        nsMemory::Free(spec);
-        return PL_DHASH_STOP;
-    }
-
-    writeEntry->mString = NS_REINTERPRET_CAST(const char*, spec);
-    writeEntry->mURI = nsnull;
-    writeEntry->mInitialSegmentOffset = readEntry->mInitialSegmentOffset;
-    writeEntry->mCurrentSegmentOffset = 0;
-    return PL_DHASH_NEXT;
-}
-
-nsresult
-nsFastLoadFileUpdater::Open(nsFastLoadFileReader* aReader)
-{
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mOutputStream));
-    if (!seekable)
-        return NS_ERROR_UNEXPECTED;
-
-    nsresult rv;
-    rv = nsFastLoadFileWriter::Init();
-    if (NS_FAILED(rv))
-        return rv;
-
-    PRUint32 i, n;
-
-    // Map from dense, zero-based, uint32 NSFastLoadID in reader to 16-byte
-    // nsID in updater.
-    nsID* readIDMap = aReader->mFooter.mIDMap;
-    for (i = 0, n = aReader->mFooter.mNumIDs; i < n; i++) {
-        NSFastLoadID fastID;
-        rv = MapID(readIDMap[i], &fastID);
-        NS_ASSERTION(fastID == i + 1, "huh?");
-        if (NS_FAILED(rv))
-            return rv;
-    }
-
-    // Map from reader dense, zero-based MFL_OID_TO_SHARP_INDEX(oid) to sharp
-    // object offset and refcnt information in updater.
-    nsFastLoadFileReader::nsObjectMapEntry* readObjectMap =
-        aReader->mFooter.mObjectMap;
-
-    // Prepare to save aReader state in case we need to seek back and read a
-    // singleton object that might otherwise get written by this updater.
-    nsDocumentMapReadEntry* saveDocMapEntry = nsnull;
-    nsCOMPtr<nsISeekableStream> inputSeekable;
-    PRInt64 saveOffset = 0;
-
-    for (i = 0, n = aReader->mFooter.mNumSharpObjects; i < n; i++) {
-        nsFastLoadFileReader::nsObjectMapEntry* readEntry = &readObjectMap[i];
-
-        NS_ASSERTION(readEntry->mCIDOffset != 0,
-                     "fastload updater: mCIDOffset cannot be zero!");
-
-        // If the reader didn't read this object but it's a singleton, we must
-        // "deserialize" it now, to discover its one and only root nsISupports
-        // address.  The object already exists in memory if it was created at
-        // startup without resort to the FastLoad file.  The canonical example
-        // is the system principal object held by all XUL JS scripts.
-
-        nsISupports* obj = readEntry->mReadObject;
-        if (!obj && MFL_GET_SINGLETON_FLAG(readEntry)) {
-            if (!saveDocMapEntry) {
-                inputSeekable = do_QueryInterface(aReader->mInputStream);
-                rv = inputSeekable->Tell(&saveOffset);
-                if (NS_FAILED(rv))
-                    return rv;
-
-                saveDocMapEntry = aReader->mCurrentDocumentMapEntry;
-                aReader->mCurrentDocumentMapEntry = nsnull;
-            }
-
-            rv = inputSeekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                                     readEntry->mCIDOffset);
-            if (NS_FAILED(rv))
-                return rv;
-
-            rv = aReader
-                 ->DeserializeObject(getter_AddRefs(readEntry->mReadObject));
-            if (NS_FAILED(rv))
-                return rv;
-            obj = readEntry->mReadObject;
-
-            // Don't forget to set mSkipOffset in case someone calls the reader
-            // to "deserialize" (yet again) the object we just read.
-            //
-            // Say the singleton is the system principal, and the FastLoad file
-            // contains data for navigator.xul including scripts and functions.
-            // If we update the FastLoad file to contain data for messenger.xul
-            // in a separate session started via mozilla -mail, *and during the
-            // same FastLoad episode in this session* race to open a navigator
-            // window, we will attempt to read all objects serialized in the
-            // navigator.xul portion of the FastLoad file.
-            //
-            // mSkipOffset must be set in such a case so the reader can skip
-            // the system principal's serialized data, because the updater for
-            // messenger.xul being opened here has already read it.
-
-            rv = inputSeekable->Tell(&readEntry->mSkipOffset);
-            if (NS_FAILED(rv))
-                return rv;
-        }
-
-        NSFastLoadOID oid = MFL_SHARP_INDEX_TO_OID(i);
-        void* key = obj
-                    ? NS_REINTERPRET_CAST(void*, obj)
-                    : NS_REINTERPRET_CAST(void*, (oid | MFL_OBJECT_DEF_TAG));
-
-        nsSharpObjectMapEntry* writeEntry =
-            NS_STATIC_CAST(nsSharpObjectMapEntry*,
-                           PL_DHashTableOperate(&mObjectMap, key,
-                                                PL_DHASH_ADD));
-        if (!writeEntry)
-            return NS_ERROR_OUT_OF_MEMORY;
-
-        // Hold the object if there is one, so that objmap_ClearEntry can
-        // release the reference.
-        NS_IF_ADDREF(obj);
-        writeEntry->mObject = NS_REINTERPRET_CAST(nsISupports*, key);
-        writeEntry->mOID = oid;
-        writeEntry->mInfo.mCIDOffset = readEntry->mCIDOffset;
-        writeEntry->mInfo.mStrongRefCnt = readEntry->mSaveStrongRefCnt;
-        writeEntry->mInfo.mWeakRefCnt = readEntry->mSaveWeakRefCnt;
-    }
-
-    // If we had to read any singletons, restore aReader's saved state.
-    if (saveDocMapEntry) {
-        rv = inputSeekable->Seek(nsISeekableStream::NS_SEEK_SET, saveOffset);
-        if (NS_FAILED(rv))
-            return rv;
-
-        aReader->mCurrentDocumentMapEntry = saveDocMapEntry;
-    }
-
-    // Copy URI spec string and initial segment offset in FastLoad file from
-    // nsDocumentMapReadEntry in reader to nsDocumentMapWriteEntry in updater.
-    // If we didn't enumerate all entries, we ran out of memory.
-    n = PL_DHashTableEnumerate(&aReader->mFooter.mDocumentMap,
-                               CopyReadDocumentMapEntryToUpdater,
-                               this);
-    if (n != aReader->mFooter.mDocumentMap.entryCount)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    // Copy source filename dependencies from reader to updater.
-    nsISupportsArray* readDeps = aReader->mFooter.mDependencies;
-    rv = readDeps->Count(&n);
-    if (NS_FAILED(rv))
-        return rv;
-
-    for (i = 0; i < n; i++) {
-        nsCOMPtr<nsIFile> file;
-        rv = readDeps->GetElementAt(i, getter_AddRefs(file));
-        if (NS_FAILED(rv))
-            return rv;
-
-        rv = AddDependency(file);
-        if (NS_FAILED(rv))
-            return rv;
-    }
-
-    // Seek to the reader's footer offset so we overwrite the footer.  First,
-    // update the header to have a zero mFooterOffset, which will invalidate
-    // the FastLoad file on next startup read attempt, should we crash before
-    // completing this update.
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                        offsetof(nsFastLoadHeader, mFooterOffset));
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = Write32(0);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET,
-                        aReader->mHeader.mFooterOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    // Avoid creating yet another object by implementing nsIFastLoadFileIO on
-    // this updater, and save aReader's input stream so it can be returned by
-    // GetInputStream called from nsFastLoadFileWriter::Close.  This requires
-    // that we override Close to break the resulting zero-length cycle.
-    mFileIO = this;
-    mInputStream = aReader->mInputStream;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadFileUpdater::Close()
-{
-    // Call base-class Close implementation, which uses mFileIO.
-    nsresult rv = nsFastLoadFileWriter::Close();
-
-    // Break degenerate cycle from this->mFileIO to this.
-    mFileIO = nsnull;
-    return rv;
-}
-
-NS_COM nsresult
-NS_NewFastLoadFileUpdater(nsIObjectOutputStream* *aResult,
-                          nsIOutputStream* aOutputStream,
-                          nsIObjectInputStream* aReaderAsStream)
-{
-    // Make sure that aReaderAsStream is an nsFastLoadFileReader.
-    nsCOMPtr<nsIFastLoadFileReader> reader(do_QueryInterface(aReaderAsStream));
-    if (!reader)
-        return NS_ERROR_UNEXPECTED;
-
-    nsFastLoadFileUpdater* updater = new nsFastLoadFileUpdater(aOutputStream);
-    if (!updater)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    // Stabilize updater's refcnt.
-    nsCOMPtr<nsIObjectOutputStream> stream(updater);
-
-    nsresult rv = updater->Open(NS_STATIC_CAST(nsFastLoadFileReader*,
-                                               aReaderAsStream));
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aResult = stream;
-    NS_ADDREF(*aResult);
-    return NS_OK;
-}
Index: trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadFile.h
===================================================================
--- trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadFile.h	(revision 101807)
+++ 	(revision )
@@ -1,566 +1,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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/
- *
- * 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.
- *
- * The Original Code is Mozilla FastLoad code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Brendan Eich <brendan@mozilla.org> (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of 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 ***** */
-
-#ifndef nsFastLoadFile_h___
-#define nsFastLoadFile_h___
-
-/**
- * Mozilla FastLoad file format and helper types.
- */
-
-#include "prtypes.h"
-#include "pldhash.h"
-
-#include "nsBinaryStream.h"
-#include "nsCOMPtr.h"
-#include "nsDebug.h"
-#include "nsID.h"
-#include "nsMemory.h"
-#include "nsVoidArray.h"
-
-#include "nsIFastLoadFileControl.h"
-#include "nsIFastLoadService.h"
-#include "nsISeekableStream.h"
-#include "nsISupportsArray.h"
-
-/**
- * FastLoad file Object ID (OID) is an identifier for multiply and cyclicly
- * connected objects in the serialized graph of all reachable objects.
- *
- * Holy Mixed Metaphors: JS, after Common Lisp, uses #n= to define a "sharp
- * variable" naming an object that's multiply or cyclicly connected, and #n#
- * to stand for a connection to an already-defined object.  We too call any
- * object with multiple references "sharp", and (here it comes) any object
- * with only one reference "dull".
- *
- * Note that only sharp objects require a mapping from OID to FastLoad file
- * offset and other information.  Dull objects can be serialized _in situ_
- * (where they are referenced) and deserialized when their (singular, shared)
- * OID is scanned.
- *
- * We also compress 16-byte XPCOM IDs into 32-bit dense identifiers to save
- * space.  See nsFastLoadFooter, below, for the mapping data structure used to
- * compute an nsID given an NSFastLoadID.
- */
-typedef PRUint32 NSFastLoadID;          // nsFastLoadFooter::mIDMap index
-typedef PRUint32 NSFastLoadOID;         // nsFastLoadFooter::mObjectMap index
-
-/**
- * A Mozilla FastLoad file is an untagged (in general) stream of objects and
- * primitive-type data.  Small integers are fairly common, and could easily be
- * confused for NSFastLoadIDs and NSFastLoadOIDs.  To help catch bugs where
- * reader and writer code fail to match, we XOR unlikely 32-bit numbers with
- * NSFastLoad*IDs when storing and fetching.  The following unlikely values are
- * irrational numbers ((sqrt(5)-1)/2, sqrt(2)-1) represented in fixed point.
- *
- * The reader XORs, converts the ID to an index, and bounds-checks all array
- * accesses that use the index.  Array access code asserts that the index is in
- * bounds, and returns a dummy array element if it isn't.
- */
-#define MFL_ID_XOR_KEY  0x9E3779B9      // key XOR'd with ID when serialized
-#define MFL_OID_XOR_KEY 0x6A09E667      // key XOR'd with OID when serialized
-
-/**
- * An OID can be tagged to introduce the serialized definition of the object,
- * or to stand for a strong or weak reference to that object.  Thus the high
- * 29 bits actually identify the object, and the low three bits tell whether
- * the object is being defined or just referenced -- and via what inheritance
- * chain or inner object, if necessary.
- *
- * The MFL_QUERY_INTERFACE_TAG bit helps us cope with aggregation and multiple
- * inheritance: object identity follows the XPCOM rule, but a deserializer may
- * need to query for an interface not on the primary inheritance chain ending
- * in the nsISupports whose address uniquely identifies the XPCOM object being
- * referenced or defined.
- */
-#define MFL_OBJECT_TAG_BITS     3
-#define MFL_OBJECT_TAG_MASK     PR_BITMASK(MFL_OBJECT_TAG_BITS)
-
-#define MFL_OBJECT_DEF_TAG      1U      // object definition follows this OID
-#define MFL_WEAK_REF_TAG        2U      // OID weakly refers to a prior object
-                                        // NB: do not confuse with nsWeakPtr!
-#define MFL_QUERY_INTERFACE_TAG 4U      // QI object to the ID follows this OID
-                                        // NB: an NSFastLoadID, not an nsIID!
-
-/**
- * The dull object identifier introduces the definition of all objects that
- * have only one (necessarily strong) ref in the serialization.  The definition
- * appears at the point of reference.
- */
-#define MFL_DULL_OBJECT_OID     MFL_OBJECT_DEF_TAG
-
-/**
- * Convert an OID to an index into nsFastLoadFooter::mObjectMap.
- */
-#define MFL_OID_TO_SHARP_INDEX(oid)     (((oid) >> MFL_OBJECT_TAG_BITS) - 1)
-#define MFL_SHARP_INDEX_TO_OID(index)   (((index) + 1) << MFL_OBJECT_TAG_BITS)
-
-/**
- * Magic "number" at start of a FastLoad file.  Inspired by the PNG "magic"
- * string, which inspired XPCOM's typelib (.xpt) file magic.  Guaranteed to be
- * corrupted by FTP-as-ASCII and other likely errors, meaningful to clued-in
- * humans, and ending in ^Z to terminate erroneous text input on Windows.
- */
-#define MFL_FILE_MAGIC          "XPCOM\nMozFASL\r\n\032"
-#define MFL_FILE_MAGIC_SIZE     16
-
-#define MFL_FILE_VERSION_0      0
-#define MFL_FILE_VERSION_1      1000
-#define MFL_FILE_VERSION        4       // fix to note singletons in object map
-
-/**
- * Compute Fletcher's 16-bit checksum over aLength bytes starting at aBuffer,
- * with the initial accumulators seeded from *aChecksum, and final checksum
- * returned in *aChecksum.  The return value is the number of unchecked bytes,
- * which may be non-zero if aBuffer is misaligned or aLength is odd.  Callers
- * should copy any remaining bytes to the front of the next buffer.
- *
- * If aLastBuffer is false, do not check any bytes remaining due to misaligned
- * aBuffer or odd aLength, instead returning the remaining byte count.  But if
- * aLastBuffer is true, treat aBuffer as the last buffer in the file and check
- * every byte, returning 0.  Here's a read-loop checksumming sketch:
- *
- *  char buf[BUFSIZE];
- *  PRUint32 len, rem = 0;
- *  PRUint32 checksum = 0;
- *
- *  while (NS_SUCCEEDED(rv = Read(buf + rem, sizeof buf - rem, &len)) && len) {
- *      len += rem;
- *      rem = NS_AccumulateFastLoadChecksum(&checksum,
- *                                          NS_REINTERPRET_CAST(PRUint8*, buf),
- *                                          len,
- *                                          PR_FALSE);
- *      if (rem)
- *          memcpy(buf, buf + len - rem, rem);
- *  }
- *
- *  if (rem) {
- *      NS_AccumulateFastLoadChecksum(&checksum,
- *                                    NS_REINTERPRET_CAST(PRUint8*, buf),
- *                                    rem,
- *                                    PR_TRUE);
- *  }
- *
- * After this, if NS_SUCCEEDED(rv), checksum contains a valid FastLoad sum.
- */
-PR_EXTERN(PRUint32)
-NS_AccumulateFastLoadChecksum(PRUint32 *aChecksum,
-                              const PRUint8* aBuffer,
-                              PRUint32 aLength,
-                              PRBool aLastBuffer);
-
-PR_EXTERN(PRUint32)
-NS_AddFastLoadChecksums(PRUint32 sum1, PRUint32 sum2, PRUint32 sum2ByteCount);
-
-/**
- * Header at the start of a FastLoad file.
- */
-struct nsFastLoadHeader {
-    char        mMagic[MFL_FILE_MAGIC_SIZE];
-    PRUint32    mChecksum;
-    PRUint32    mVersion;
-    PRUint32    mFooterOffset;
-    PRUint32    mFileSize;
-};
-
-/**
- * Footer prefix structure (footer header, ugh), after which come arrays of
- * structures or strings counted by these members.
- */
-struct nsFastLoadFooterPrefix {
-    PRUint32    mNumIDs;
-    PRUint32    mNumSharpObjects;
-    PRUint32    mNumMuxedDocuments;
-    PRUint32    mNumDependencies;
-};
-
-struct nsFastLoadSharpObjectInfo {
-    PRUint32    mCIDOffset;     // offset of object's NSFastLoadID and data
-    PRUint16    mStrongRefCnt;
-    PRUint16    mWeakRefCnt;    // high bit is singleton flag, see below
-};
-
-#define MFL_SINGLETON_FLAG          0x8000
-#define MFL_WEAK_REFCNT_MASK        0x7fff
-
-#define MFL_GET_SINGLETON_FLAG(ip)  ((ip)->mWeakRefCnt & MFL_SINGLETON_FLAG)
-#define MFL_GET_WEAK_REFCNT(ip)     ((ip)->mWeakRefCnt & MFL_WEAK_REFCNT_MASK)
-
-#define MFL_SET_SINGLETON_FLAG(ip)                                            \
-    ((ip)->mWeakRefCnt |= MFL_SINGLETON_FLAG)
-#define MFL_SET_WEAK_REFCNT(ip,rc)                                            \
-    ((ip)->mWeakRefCnt = (((ip)->mWeakRefCnt & MFL_SINGLETON_FLAG) | (rc)))
-
-#define MFL_BUMP_WEAK_REFCNT(ip)    (++(ip)->mWeakRefCnt)
-#define MFL_DROP_WEAK_REFCNT(ip)    (--(ip)->mWeakRefCnt)
-
-struct nsFastLoadMuxedDocumentInfo {
-    const char* mURISpec;
-    PRUint32    mInitialSegmentOffset;
-};
-
-// forward declarations of opaque types defined in nsFastLoadFile.cpp
-struct nsDocumentMapReadEntry;
-struct nsDocumentMapWriteEntry;
-
-// So nsFastLoadFileUpdater can verify that its nsIObjectInputStream parameter
-// is an nsFastLoadFileReader.
-#define NS_FASTLOADFILEREADER_IID \
-    {0x7d37d1bb,0xcef3,0x4c5f,{0x97,0x68,0x0f,0x89,0x7f,0x1a,0xe1,0x40}}
-
-struct nsIFastLoadFileReader : public nsISupports {
-    NS_DEFINE_STATIC_IID_ACCESSOR(NS_FASTLOADFILEREADER_IID)
-};
-
-/**
- * Inherit from the concrete class nsBinaryInputStream, which inherits from
- * abstract nsIObjectInputStream but does not implement its direct methods.
- * Though the names are not as clear as I'd like, this seems to be the best
- * way to share nsBinaryStream.cpp code.
- */
-class nsFastLoadFileReader
-    : public nsBinaryInputStream,
-      public nsIFastLoadReadControl,
-      public nsISeekableStream,
-      public nsIFastLoadFileReader
-{
-  public:
-    nsFastLoadFileReader(nsIInputStream *aStream)
-      : mCurrentDocumentMapEntry(nsnull) {
-        SetInputStream(aStream);
-        MOZ_COUNT_CTOR(nsFastLoadFileReader);
-    }
-
-    virtual ~nsFastLoadFileReader() {
-        MOZ_COUNT_DTOR(nsFastLoadFileReader);
-    }
-
-  private:
-    // nsISupports methods
-    NS_DECL_ISUPPORTS_INHERITED
-
-    // overridden nsIObjectInputStream methods
-    NS_IMETHOD ReadObject(PRBool aIsStrongRef, nsISupports* *_retval);
-    NS_IMETHOD ReadID(nsID *aResult);
-
-    // nsIFastLoadFileControl methods
-    NS_DECL_NSIFASTLOADFILECONTROL
-
-    // nsIFastLoadReadControl methods
-    NS_DECL_NSIFASTLOADREADCONTROL
-
-    // nsISeekableStream methods
-    NS_DECL_NSISEEKABLESTREAM
-
-    // Override Read so we can demultiplex a document interleaved with others.
-    NS_IMETHOD Read(char* aBuffer, PRUint32 aCount, PRUint32 *aBytesRead);
-
-    // Override ReadSegments too, as nsBinaryInputStream::ReadSegments does
-    // not call through our overridden Read method -- it calls directly into
-    // the underlying input stream.
-    NS_IMETHODIMP ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
-                               PRUint32 aCount, PRUint32 *aResult);
-
-    nsresult ReadHeader(nsFastLoadHeader *aHeader);
-
-    /**
-     * In-memory representation of an indexed nsFastLoadSharpObjectInfo record.
-     */
-    struct nsObjectMapEntry : public nsFastLoadSharpObjectInfo {
-        nsCOMPtr<nsISupports>   mReadObject;
-        PRInt64                 mSkipOffset;
-        PRUint16                mSaveStrongRefCnt;      // saved for an Update
-        PRUint16                mSaveWeakRefCnt;        // after a Read
-    };
-
-    /**
-     * In-memory representation of the FastLoad file footer.
-     */
-    struct nsFastLoadFooter : public nsFastLoadFooterPrefix {
-        nsFastLoadFooter()
-          : mIDMap(nsnull),
-            mObjectMap(nsnull) {
-            mDocumentMap.ops = mURIMap.ops = nsnull;
-        }
-
-        ~nsFastLoadFooter() {
-            delete[] mIDMap;
-            delete[] mObjectMap;
-            if (mDocumentMap.ops)
-                PL_DHashTableFinish(&mDocumentMap);
-            if (mURIMap.ops)
-                PL_DHashTableFinish(&mURIMap);
-        }
-
-        // These can't be static within GetID and GetSharpObjectEntry or the
-        // toolchains on HP-UX 10.20's, RH 7.0, and Mac OS X all barf at link
-        // time ("common symbols not allowed with MY_DHLIB output format", to
-        // quote the OS X rev of gcc).
-        static nsID gDummyID;
-        static nsObjectMapEntry gDummySharpObjectEntry;
-
-        const nsID& GetID(NSFastLoadID aFastId) const {
-            PRUint32 index = aFastId - 1;
-            NS_ASSERTION(index < mNumIDs, "aFastId out of range");
-            if (index >= mNumIDs)
-                return gDummyID;
-            return mIDMap[index];
-        }
-
-        nsObjectMapEntry&
-        GetSharpObjectEntry(NSFastLoadOID aOID) const {
-            PRUint32 index = MFL_OID_TO_SHARP_INDEX(aOID);
-            NS_ASSERTION(index < mNumSharpObjects, "aOID out of range");
-            if (index >= mNumSharpObjects)
-                return gDummySharpObjectEntry;
-            return mObjectMap[index];
-        }
-
-        // Map from dense, zero-based, uint32 NSFastLoadID to 16-byte nsID.
-        nsID* mIDMap;
-
-        // Map from dense, zero-based MFL_OID_TO_SHARP_INDEX(oid) to sharp
-        // object offset and refcnt information.
-        nsObjectMapEntry* mObjectMap;
-
-        // Map from URI spec string to nsDocumentMapReadEntry, which helps us
-        // demultiplex a document's objects from among the interleaved object
-        // stream segments in the FastLoad file.
-        PLDHashTable mDocumentMap;
-
-        // Fast mapping from URI object pointer to mDocumentMap entry, valid
-        // only while the muxed document is loading.
-        PLDHashTable mURIMap;
-
-        // List of source filename dependencies that should trigger regeneration
-        // of the FastLoad file.
-        nsCOMPtr<nsISupportsArray> mDependencies;
-    };
-
-    nsresult ReadFooter(nsFastLoadFooter *aFooter);
-    nsresult ReadFooterPrefix(nsFastLoadFooterPrefix *aFooterPrefix);
-    nsresult ReadSlowID(nsID *aID);
-    nsresult ReadFastID(NSFastLoadID *aID);
-    nsresult ReadSharpObjectInfo(nsFastLoadSharpObjectInfo *aInfo);
-    nsresult ReadMuxedDocumentInfo(nsFastLoadMuxedDocumentInfo *aInfo);
-    nsresult DeserializeObject(nsISupports* *aObject);
-
-    nsresult   Open();
-    NS_IMETHOD Close();
-
-  protected:
-    nsFastLoadHeader mHeader;
-    nsFastLoadFooter mFooter;
-
-    nsDocumentMapReadEntry* mCurrentDocumentMapEntry;
-
-    friend class nsFastLoadFileUpdater;
-};
-
-NS_COM nsresult
-NS_NewFastLoadFileReader(nsIObjectInputStream* *aResult,
-                         nsIInputStream* aSrcStream);
-
-/**
- * Inherit from the concrete class nsBinaryInputStream, which inherits from
- * abstract nsIObjectInputStream but does not implement its direct methods.
- * Though the names are not as clear as I'd like, this seems to be the best
- * way to share nsBinaryStream.cpp code.
- */
-class nsFastLoadFileWriter
-    : public nsBinaryOutputStream,
-      public nsIFastLoadWriteControl,
-      public nsISeekableStream
-{
-  public:
-    nsFastLoadFileWriter(nsIOutputStream *aStream, nsIFastLoadFileIO* aFileIO)
-      : mCurrentDocumentMapEntry(nsnull),
-        mFileIO(aFileIO)
-    {
-        SetOutputStream(aStream);
-        mHeader.mChecksum = 0;
-        mIDMap.ops = mObjectMap.ops = mDocumentMap.ops = mURIMap.ops = nsnull;
-        mDependencyMap.ops = nsnull;
-        MOZ_COUNT_CTOR(nsFastLoadFileWriter);
-    }
-
-    virtual ~nsFastLoadFileWriter()
-    {
-        if (mIDMap.ops)
-            PL_DHashTableFinish(&mIDMap);
-        if (mObjectMap.ops)
-            PL_DHashTableFinish(&mObjectMap);
-        if (mDocumentMap.ops)
-            PL_DHashTableFinish(&mDocumentMap);
-        if (mURIMap.ops)
-            PL_DHashTableFinish(&mURIMap);
-        if (mDependencyMap.ops)
-            PL_DHashTableFinish(&mDependencyMap);
-        MOZ_COUNT_DTOR(nsFastLoadFileWriter);
-    }
-
-  private:
-    // nsISupports methods
-    NS_DECL_ISUPPORTS_INHERITED
-
-    // overridden nsIObjectOutputStream methods
-    NS_IMETHOD WriteObject(nsISupports* aObject, PRBool aIsStrongRef);
-    NS_IMETHOD WriteSingleRefObject(nsISupports* aObject);
-    NS_IMETHOD WriteCompoundObject(nsISupports* aObject,
-                                   const nsIID& aIID,
-                                   PRBool aIsStrongRef);
-    NS_IMETHOD WriteID(const nsID& aID);
-
-    // nsIFastLoadFileControl methods
-    NS_DECL_NSIFASTLOADFILECONTROL
-
-    // nsIFastLoadWriteControl methods
-    NS_DECL_NSIFASTLOADWRITECONTROL
-
-    // nsISeekableStream methods
-    NS_DECL_NSISEEKABLESTREAM
-
-    nsresult MapID(const nsID& aSlowID, NSFastLoadID *aResult);
-
-    nsresult WriteHeader(nsFastLoadHeader *aHeader);
-    nsresult WriteFooter();
-    nsresult WriteFooterPrefix(const nsFastLoadFooterPrefix& aFooterPrefix);
-    nsresult WriteSlowID(const nsID& aID);
-    nsresult WriteFastID(NSFastLoadID aID);
-    nsresult WriteSharpObjectInfo(const nsFastLoadSharpObjectInfo& aInfo);
-    nsresult WriteMuxedDocumentInfo(const nsFastLoadMuxedDocumentInfo& aInfo);
-
-    nsresult   Init();
-    nsresult   Open();
-    NS_IMETHOD Close();
-
-    nsresult WriteObjectCommon(nsISupports* aObject,
-                               PRBool aIsStrongRef,
-                               PRUint32 aQITag);
-
-    static PLDHashOperator PR_CALLBACK
-    IDMapEnumerate(PLDHashTable *aTable,
-                   PLDHashEntryHdr *aHdr,
-                   PRUint32 aNumber,
-                   void *aData);
-
-    static PLDHashOperator PR_CALLBACK
-    ObjectMapEnumerate(PLDHashTable *aTable,
-                       PLDHashEntryHdr *aHdr,
-                       PRUint32 aNumber,
-                       void *aData);
-
-    static PLDHashOperator PR_CALLBACK
-    DocumentMapEnumerate(PLDHashTable *aTable,
-                         PLDHashEntryHdr *aHdr,
-                         PRUint32 aNumber,
-                         void *aData);
-
-    static PLDHashOperator PR_CALLBACK
-    DependencyMapEnumerate(PLDHashTable *aTable,
-                           PLDHashEntryHdr *aHdr,
-                           PRUint32 aNumber,
-                           void *aData);
-
-  protected:
-    nsFastLoadHeader mHeader;
-
-    PLDHashTable mIDMap;
-    PLDHashTable mObjectMap;
-    PLDHashTable mDocumentMap;
-    PLDHashTable mURIMap;
-    PLDHashTable mDependencyMap;
-
-    nsDocumentMapWriteEntry* mCurrentDocumentMapEntry;
-    nsCOMPtr<nsIFastLoadFileIO> mFileIO;
-};
-
-NS_COM nsresult
-NS_NewFastLoadFileWriter(nsIObjectOutputStream* *aResult,
-                         nsIOutputStream* aDestStream,
-                         nsIFastLoadFileIO* aFileIO);
-
-/**
- * Subclass of nsFastLoadFileWriter, friend of nsFastLoadFileReader which it
- * wraps when a FastLoad file needs to be updated.  The wrapped reader can be
- * used to demulitplex data for documents already in the FastLoad file, while
- * the updater writes new data over the old footer, then writes a new footer
- * that maps all data on Close.
- */
-class nsFastLoadFileUpdater
-    : public nsFastLoadFileWriter,
-             nsIFastLoadFileIO
-{
-  public:
-    nsFastLoadFileUpdater(nsIOutputStream* aOutputStream)
-      : nsFastLoadFileWriter(aOutputStream, nsnull) {
-        MOZ_COUNT_CTOR(nsFastLoadFileUpdater);
-    }
-
-    virtual ~nsFastLoadFileUpdater() {
-        MOZ_COUNT_DTOR(nsFastLoadFileUpdater);
-    }
-
-  private:
-    // nsISupports methods
-    NS_DECL_ISUPPORTS_INHERITED
-
-    // nsIFastLoadFileIO methods
-    NS_DECL_NSIFASTLOADFILEIO
-
-    nsresult   Open(nsFastLoadFileReader* aReader);
-    NS_IMETHOD Close();
-
-    static PLDHashOperator PR_CALLBACK
-    CopyReadDocumentMapEntryToUpdater(PLDHashTable *aTable,
-                                      PLDHashEntryHdr *aHdr,
-                                      PRUint32 aNumber,
-                                      void *aData);
-
-    friend class nsFastLoadFileReader;
-
-  protected:
-    nsCOMPtr<nsIInputStream> mInputStream;
-};
-
-NS_COM nsresult
-NS_NewFastLoadFileUpdater(nsIObjectOutputStream* *aResult,
-                          nsIOutputStream* aOutputStream,
-                          nsIObjectInputStream* aReaderAsStream);
-
-#endif // nsFastLoadFile_h___
Index: trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadPtr.h
===================================================================
--- trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadPtr.h	(revision 101807)
+++ 	(revision )
@@ -1,112 +1,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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/
- *
- * 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.
- *
- * The Original Code is Mozilla FastLoad code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Brendan Eich <brendan@mozilla.org> (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of 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 ***** */
-
-#ifndef nsFastLoadPtr_h___
-#define nsFastLoadPtr_h___
-
-/**
- * Mozilla FastLoad file object pointer template type.
- *
- * Use nsFastLoadPtr<T> rather than nsCOMPtr<T> when declaring a strong XPCOM
- * ref member of a data structure that's conditionally loaded at application
- * startup.  You must be willing to tolerate the null mRawPtr test on every
- * dereference of this member pointer, or else copy it to a local to optimize
- * away the cost.
- */
-
-#ifndef nsCOMPtr_h___
-#include "nsCOMPtr.h"
-#endif
-
-#ifndef nsIFastLoadService_h___
-#include "nsIFastLoadService.h"
-#endif
-
-#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
-#define gFastLoadService_ VBoxNsxpgFastLoadService_
-#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
-
-/**
- * nsFastLoadPtr is a template class, so we don't want a class static service
- * pointer member declared in nsFastLoadPtr, above.  Plus, we need special
- * declaration magic to export data across DLL/DSO boundaries.  So we use an
- * old-fashioned global variable that refers weakly to the one true FastLoad
- * service.  This pointer is maintained by that singleton's ctor and dtor.
- */
-PR_EXPORT_DATA(nsIFastLoadService*) gFastLoadService_;
-
-template <class T>
-class nsFastLoadPtr : public nsCOMPtr<T> {
-  public:
-    nsDerivedSafe<T>* get() const {
-        if (!this->mRawPtr) {
-            gFastLoadService_->GetFastLoadReferent(
-                                         NS_REINTERPRET_CAST(nsISupports**,
-                                                             &this->mRawPtr));
-        }
-        return NS_REINTERPRET_CAST(nsDerivedSafe<T>*, this->mRawPtr);
-    }
-
-    /**
-     * Deserialize an nsFastLoadPtr from aInputStream, skipping the referent
-     * object, but saving the object's offset for later deserialization.
-     *
-     * Lowercase name _a la_ get, because it's called the same way -- not via
-     * operator->().
-     */
-    nsresult read(nsIObjectInputStream* aInputStream) {
-        return gFastLoadService_->ReadFastLoadPtr(aInputStream,
-                                         NS_REINTERPRET_CAST(nsISupports**,
-                                                             &this->mRawPtr));
-    }
-
-    /**
-     * Serialize an nsFastLoadPtr reference and possibly the referent object,
-     * if that object has not yet been serialized.
-     *
-     * Lowercase name _a la_ get, because it's called the same way -- not via
-     * operator->().
-     */
-    nsresult write(nsIObjectOutputStream* aOutputStream) {
-        return gFastLoadService_->WriteFastLoadPtr(aOutputStream,
-                                          NS_REINTERPRET_CAST(nsISupports*,
-                                                              this->mRawPtr));
-    }
-};
-
-#endif // nsFastLoadPtr_h___
Index: trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadService.cpp
===================================================================
--- trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadService.cpp	(revision 101807)
+++ 	(revision )
@@ -1,571 +1,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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/
- *
- * 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.
- *
- * The Original Code is Mozilla FastLoad code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Brendan Eich <brendan@mozilla.org> (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of 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 ***** */
-
-#include "prtypes.h"
-#include "prio.h"
-#include "prtime.h"
-#include "pldhash.h"
-
-#include "nsAppDirectoryServiceDefs.h"
-#include "nsAutoLock.h"
-#include "nsCOMPtr.h"
-#include "nsFastLoadFile.h"
-#include "nsFastLoadPtr.h"
-#include "nsFastLoadService.h"
-#include "nsString.h"
-
-#include "nsIComponentManager.h"
-#include "nsIEnumerator.h"
-#include "nsIFastLoadFileControl.h"
-#include "nsIFile.h"
-#include "nsIObjectInputStream.h"
-#include "nsIObjectOutputStream.h"
-#include "nsISeekableStream.h"
-#include "nsISupports.h"
-
-PR_IMPLEMENT_DATA(nsIFastLoadService*) gFastLoadService_ = nsnull;
-
-NS_IMPL_THREADSAFE_ISUPPORTS1(nsFastLoadService, nsIFastLoadService)
-
-nsFastLoadService::nsFastLoadService()
-  : mLock(nsnull),
-    mFastLoadPtrMap(nsnull),
-    mDirection(0)
-{
-    NS_ASSERTION(gFastLoadService_ == nsnull, "double FastLoadService init?");
-    gFastLoadService_ = this;
-}
-
-nsFastLoadService::~nsFastLoadService()
-{
-    gFastLoadService_ = nsnull;
-
-    if (mInputStream)
-        mInputStream->Close();
-    if (mOutputStream)
-        mOutputStream->Close();
-
-    if (mFastLoadPtrMap)
-        PL_DHashTableDestroy(mFastLoadPtrMap);
-    if (mLock)
-        PR_DestroyLock(mLock);
-}
-
-NS_IMETHODIMP
-nsFastLoadService::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
-{
-    *aResult = nsnull;
-    if (aOuter)
-        return NS_ERROR_NO_AGGREGATION;
-
-    nsFastLoadService* fastLoadService = new nsFastLoadService();
-    if (!fastLoadService)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    fastLoadService->mLock = PR_NewLock();
-    if (!fastLoadService->mLock) {
-        delete fastLoadService;
-        return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    NS_ADDREF(fastLoadService);
-    nsresult rv = fastLoadService->QueryInterface(aIID, aResult);
-    NS_RELEASE(fastLoadService);
-    return rv;
-}
-
-#if defined XP_MAC
-
-// Mac format: "<Basename> FastLoad File" with <basename> capitalized.
-# include "nsCRT.h"
-
-# define MASSAGE_BASENAME(bn)   (bn.SetCharAt(nsCRT::ToUpper(bn.CharAt(0)), 0))
-# define PLATFORM_FASL_SUFFIX   " FastLoad File"
-
-#elif defined(XP_UNIX) || defined(XP_BEOS)
-
-// Unix format: "<basename>.mfasl".
-# define MASSAGE_BASENAME(bn)   /* nothing */
-# define PLATFORM_FASL_SUFFIX   ".mfasl"
-
-#elif defined(XP_WIN) || defined(XP_OS2)
-
-// Windows format: "<basename>.mfl".
-# define MASSAGE_BASENAME(bn)   /* nothing */
-# define PLATFORM_FASL_SUFFIX   ".mfl"
-
-#endif
-
-nsresult
-nsFastLoadService::NewFastLoadFile(const char* aBaseName, nsIFile* *aResult)
-{
-    nsresult rv;
-    nsCOMPtr<nsIFile> file;
-
-    rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                getter_AddRefs(file));
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCAutoString name(aBaseName);
-    MASSAGE_BASENAME(name);
-    name += PLATFORM_FASL_SUFFIX;
-    rv = file->AppendNative(name);
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aResult = file;
-    NS_ADDREF(*aResult);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::NewInputStream(nsIInputStream* aSrcStream,
-                                  nsIObjectInputStream* *aResult)
-{
-    nsAutoLock lock(mLock);
-
-    nsCOMPtr<nsIObjectInputStream> stream;
-    nsresult rv = NS_NewFastLoadFileReader(getter_AddRefs(stream), aSrcStream);
-    if (NS_FAILED(rv))
-        return rv;
-
-    *aResult = stream;
-    NS_ADDREF(*aResult);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::NewOutputStream(nsIOutputStream* aDestStream,
-                                   nsIObjectOutputStream* *aResult)
-{
-    nsAutoLock lock(mLock);
-
-    return NS_NewFastLoadFileWriter(aResult, aDestStream, mFileIO);
-}
-
-NS_IMETHODIMP
-nsFastLoadService::GetInputStream(nsIObjectInputStream* *aResult)
-{
-    NS_IF_ADDREF(*aResult = mInputStream);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::SetInputStream(nsIObjectInputStream* aStream)
-{
-    nsAutoLock lock(mLock);
-    mInputStream = aStream;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::GetOutputStream(nsIObjectOutputStream* *aResult)
-{
-    NS_IF_ADDREF(*aResult = mOutputStream);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::SetOutputStream(nsIObjectOutputStream* aStream)
-{
-    nsAutoLock lock(mLock);
-    mOutputStream = aStream;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::GetFileIO(nsIFastLoadFileIO* *aResult)
-{
-    NS_IF_ADDREF(*aResult = mFileIO);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::SetFileIO(nsIFastLoadFileIO* aFileIO)
-{
-    nsAutoLock lock(mLock);
-    mFileIO = aFileIO;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::GetDirection(PRInt32 *aResult)
-{
-    *aResult = mDirection;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::HasMuxedDocument(const char* aURISpec, PRBool *aResult)
-{
-    nsresult rv = NS_ERROR_NOT_AVAILABLE;
-    nsCOMPtr<nsIFastLoadFileControl> control;
-
-    *aResult = PR_FALSE;
-    nsAutoLock lock(mLock);
-
-    if (mInputStream) {
-        control = do_QueryInterface(mInputStream);
-        if (control)
-            rv = control->HasMuxedDocument(aURISpec, aResult);
-    }
-
-    if (! *aResult && mOutputStream) {
-        control = do_QueryInterface(mOutputStream);
-        if (control)
-            rv = control->HasMuxedDocument(aURISpec, aResult);
-    }
-
-    return rv;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::StartMuxedDocument(nsISupports* aURI, const char* aURISpec,
-                                      PRInt32 aDirectionFlags)
-{
-    nsresult rv = NS_ERROR_NOT_AVAILABLE;
-    nsCOMPtr<nsIFastLoadFileControl> control;
-    nsAutoLock lock(mLock);
-
-    // Try for an input stream first, in case aURISpec's data is multiplexed
-    // in the current FastLoad file.
-    if ((aDirectionFlags & NS_FASTLOAD_READ) && mInputStream) {
-        control = do_QueryInterface(mInputStream);
-        if (control) {
-            // If aURISpec is not in the multiplex, control->StartMuxedDocument
-            // will return NS_ERROR_NOT_AVAILABLE.
-            rv = control->StartMuxedDocument(aURI, aURISpec);
-            if (NS_SUCCEEDED(rv) || rv != NS_ERROR_NOT_AVAILABLE)
-                return rv;
-
-            // Ok, aURISpec is not in the existing mux.  If we have no output
-            // stream yet, wrap the reader with a FastLoad file updater.
-            if (!mOutputStream && mFileIO) {
-                nsCOMPtr<nsIOutputStream> output;
-                rv = mFileIO->GetOutputStream(getter_AddRefs(output));
-                if (NS_FAILED(rv))
-                    return rv;
-
-                // NB: mInputStream must be an nsFastLoadFileReader!
-                rv = NS_NewFastLoadFileUpdater(getter_AddRefs(mOutputStream),
-                                               output,
-                                               mInputStream);
-                if (NS_FAILED(rv))
-                    return rv;
-            }
-
-            if (aDirectionFlags == NS_FASTLOAD_READ) {
-                // Tell our caller to re-start multiplexing, rather than attempt
-                // to select and deserialize now.
-                return NS_ERROR_NOT_AVAILABLE;
-            }
-        }
-    }
-
-    if ((aDirectionFlags & NS_FASTLOAD_WRITE) && mOutputStream) {
-        control = do_QueryInterface(mOutputStream);
-        if (control)
-            rv = control->StartMuxedDocument(aURI, aURISpec);
-    }
-    return rv;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::SelectMuxedDocument(nsISupports* aURI, nsISupports** aResult)
-{
-    nsresult rv = NS_ERROR_NOT_AVAILABLE;
-    nsCOMPtr<nsIFastLoadFileControl> control;
-    nsAutoLock lock(mLock);
-
-    // Try to select the reader, if any; then only if the URI was not in the
-    // file already, select the writer/updater.
-    if (mInputStream) {
-        control = do_QueryInterface(mInputStream);
-        if (control) {
-            rv = control->SelectMuxedDocument(aURI, aResult);
-            if (NS_SUCCEEDED(rv))
-                mDirection = NS_FASTLOAD_READ;
-        }
-    }
-
-    if (rv == NS_ERROR_NOT_AVAILABLE && mOutputStream) {
-        control = do_QueryInterface(mOutputStream);
-        if (control) {
-            rv = control->SelectMuxedDocument(aURI, aResult);
-            if (NS_SUCCEEDED(rv))
-                mDirection = NS_FASTLOAD_WRITE;
-        }
-    }
-
-    return rv;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::EndMuxedDocument(nsISupports* aURI)
-{
-    nsresult rv = NS_ERROR_NOT_AVAILABLE;
-    nsCOMPtr<nsIFastLoadFileControl> control;
-    nsAutoLock lock(mLock);
-
-    // Try to end the document identified by aURI in the reader, if any; then
-    // only if the URI was not in the file already, end the writer/updater.
-    if (mInputStream) {
-        control = do_QueryInterface(mInputStream);
-        if (control)
-            rv = control->EndMuxedDocument(aURI);
-    }
-
-    if (rv == NS_ERROR_NOT_AVAILABLE && mOutputStream) {
-        control = do_QueryInterface(mOutputStream);
-        if (control)
-            rv = control->EndMuxedDocument(aURI);
-    }
-
-    mDirection = 0;
-    return rv;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::AddDependency(nsIFile* aFile)
-{
-    nsAutoLock lock(mLock);
-
-    nsCOMPtr<nsIFastLoadWriteControl> control(do_QueryInterface(mOutputStream));
-    if (!control)
-        return NS_ERROR_NOT_AVAILABLE;
-
-    return control->AddDependency(aFile);
-}
-
-NS_IMETHODIMP
-nsFastLoadService::ComputeChecksum(nsIFile* aFile,
-                                   nsIFastLoadReadControl* aControl,
-                                   PRUint32 *aChecksum)
-{
-    nsCAutoString path;
-    nsresult rv = aFile->GetNativePath(path);
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCStringKey key(path);
-    PRUint32 checksum = NS_PTR_TO_INT32(mChecksumTable.Get(&key));
-    if (checksum) {
-        *aChecksum = checksum;
-        return NS_OK;
-    }
-
-    rv = aControl->ComputeChecksum(&checksum);
-    if (NS_FAILED(rv))
-        return rv;
-
-#ifndef VBOX
-    mChecksumTable.Put(&key, NS_INT32_TO_PTR(checksum));
-#else /* VBOX */
-    mChecksumTable.Put(&key, (void *)(uintptr_t)checksum);
-#endif /* VBOX */
-    *aChecksum = checksum;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::CacheChecksum(nsIFile* aFile, nsIObjectOutputStream *aStream)
-{
-    nsCOMPtr<nsIFastLoadFileControl> control(do_QueryInterface(aStream));
-    if (!control)
-        return NS_ERROR_FAILURE;
-
-    PRUint32 checksum;
-    nsresult rv = control->GetChecksum(&checksum);
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCAutoString path;
-    rv = aFile->GetNativePath(path);
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCStringKey key(path);
-#ifndef VBOX
-    mChecksumTable.Put(&key, NS_INT32_TO_PTR(checksum));
-#else /* VBOX */
-    mChecksumTable.Put(&key, (void *)(uintptr_t)checksum);
-#endif /* VBOX */
-    return NS_OK;
-}
-
-struct nsFastLoadPtrEntry : public PLDHashEntryHdr {
-    nsISupports** mPtrAddr;     // key, must come first for PL_DHashGetStubOps
-    PRUint32      mOffset;
-};
-
-NS_IMETHODIMP
-nsFastLoadService::GetFastLoadReferent(nsISupports* *aPtrAddr)
-{
-    NS_ASSERTION(*aPtrAddr == nsnull,
-                 "aPtrAddr doesn't point to null nsFastLoadPtr<T>::mRawAddr?");
-
-    nsAutoLock lock(mLock);
-    if (!mFastLoadPtrMap || !mInputStream)
-        return NS_OK;
-
-    nsFastLoadPtrEntry* entry =
-        NS_STATIC_CAST(nsFastLoadPtrEntry*,
-                       PL_DHashTableOperate(mFastLoadPtrMap, aPtrAddr,
-                                            PL_DHASH_LOOKUP));
-    if (PL_DHASH_ENTRY_IS_FREE(entry))
-        return NS_OK;
-
-    nsresult rv;
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(mInputStream));
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, entry->mOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = mInputStream->ReadObject(PR_TRUE, aPtrAddr);
-    if (NS_FAILED(rv))
-        return rv;
-
-    // Shrink the table if half the entries are removed sentinels.
-    PRUint32 size = PL_DHASH_TABLE_SIZE(mFastLoadPtrMap);
-    if (mFastLoadPtrMap->removedCount >= (size >> 2))
-        PL_DHashTableOperate(mFastLoadPtrMap, entry, PL_DHASH_REMOVE);
-    else
-        PL_DHashTableRawRemove(mFastLoadPtrMap, entry);
-
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::ReadFastLoadPtr(nsIObjectInputStream* aInputStream,
-                                   nsISupports* *aPtrAddr)
-{
-    // nsFastLoadPtrs self-construct to null, so if we have a non-null value
-    // in our inout parameter, we must have been read already, alright!
-    if (*aPtrAddr)
-        return NS_OK;
-
-    nsresult rv;
-    PRUint32 nextOffset;
-    nsAutoLock lock(mLock);
-
-    rv = aInputStream->Read32(&nextOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(aInputStream));
-    if (!seekable)
-        return NS_ERROR_FAILURE;
-
-    PRInt64 thisOffset;
-    rv = seekable->Tell(&thisOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, nextOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    if (!mFastLoadPtrMap) {
-        mFastLoadPtrMap = PL_NewDHashTable(PL_DHashGetStubOps(), this,
-                                           sizeof(nsFastLoadPtrEntry),
-                                           PL_DHASH_MIN_SIZE);
-        if (!mFastLoadPtrMap)
-            return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    nsFastLoadPtrEntry* entry =
-        NS_STATIC_CAST(nsFastLoadPtrEntry*,
-                       PL_DHashTableOperate(mFastLoadPtrMap, aPtrAddr,
-                                            PL_DHASH_ADD));
-    NS_ASSERTION(entry->mPtrAddr == nsnull, "duplicate nsFastLoadPtr?!");
-
-    entry->mPtrAddr = aPtrAddr;
-
-    LL_L2UI(entry->mOffset, thisOffset);
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsFastLoadService::WriteFastLoadPtr(nsIObjectOutputStream* aOutputStream,
-                                    nsISupports* aObject)
-{
-    NS_ASSERTION(aObject != nsnull, "writing an unread nsFastLoadPtr?!");
-    if (!aObject)
-        return NS_ERROR_UNEXPECTED;
-
-    nsresult rv;
-    nsAutoLock lock(mLock);     // serialize writes to aOutputStream
-
-    nsCOMPtr<nsISeekableStream> seekable(do_QueryInterface(aOutputStream));
-    if (!seekable)
-        return NS_ERROR_FAILURE;
-
-    PRInt64 saveOffset;
-    rv = seekable->Tell(&saveOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = aOutputStream->Write32(0);       // nextOffset placeholder
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = aOutputStream->WriteObject(aObject, PR_TRUE);
-    if (NS_FAILED(rv))
-        return rv;
-
-    PRInt64 nextOffset;
-    rv = seekable->Tell(&nextOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, saveOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = aOutputStream->Write32(nextOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, nextOffset);
-    if (NS_FAILED(rv))
-        return rv;
-
-    return NS_OK;
-}
Index: trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadService.h
===================================================================
--- trunk/src/libs/xpcom18a4/xpcom/io/nsFastLoadService.h	(revision 101807)
+++ 	(revision )
@@ -1,71 +1,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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/
- *
- * 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.
- *
- * The Original Code is Mozilla FastLoad code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Brendan Eich <brendan@mozilla.org> (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of 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 ***** */
-#include "prtypes.h"
-#include "pldhash.h"
-#include "nsCOMPtr.h"
-#include "nsHashtable.h"
-#include "nsIFastLoadService.h"
-#include "nsIObjectInputStream.h"
-#include "nsIObjectOutputStream.h"
-
-class nsFastLoadFileReader;
-class nsFastLoadFileWriter;
-
-class nsFastLoadService : public nsIFastLoadService
-{
-  public:
-    nsFastLoadService();
-  private:
-    ~nsFastLoadService();
-
-  public:
-    NS_DECL_ISUPPORTS
-    NS_DECL_NSIFASTLOADSERVICE
-
-    static NS_METHOD
-    Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
-
-  private:
-    PRLock*                         mLock;
-    PLDHashTable*                   mFastLoadPtrMap;
-    nsCOMPtr<nsIObjectInputStream>  mInputStream;
-    nsCOMPtr<nsIObjectOutputStream> mOutputStream;
-    nsCOMPtr<nsIFastLoadFileIO>     mFileIO;
-    PRInt32                         mDirection;
-    nsHashtable                     mChecksumTable;
-};
Index: trunk/src/libs/xpcom18a4/xpcom/io/nsIFastLoadFileControl.idl
===================================================================
--- trunk/src/libs/xpcom18a4/xpcom/io/nsIFastLoadFileControl.idl	(revision 101807)
+++ 	(revision )
@@ -1,123 +1,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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/
- *
- * 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.
- *
- * The Original Code is Mozilla FastLoad code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Brendan Eich <brendan@mozilla.org> (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of 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 ***** */
-
-#include "nsISupports.idl"
-#include "nsrootidl.idl"
-
-interface nsIFile;
-interface nsISimpleEnumerator;
-
-/**
- * The nsIFastLoadFileControl interface and its subinterfaces are mix-ins for
- * classes implementing nsIObjectInputStream and nsIObjectOutputStream, so that
- * those stream types can be used with nsIFastLoadService to access and compute
- * FastLoad file checksums, update and check FastLoad file dependencies, and
- * multiplex documents loaded via non-blocking i/o.
- *
- * If an nsIObjectInputStream class doesn't support nsIFastLoadReadControl, or
- * an nsIObjectOutputStream class doesn't support nsIFastLoadWriteControl, that
- * implementation may still be useful for object serialization, but it can't be
- * used to read or write a Mozilla FastLoad file.
- */
-[scriptable, uuid(8a1e2c63-af50-4147-af7e-26289dc180dd)]
-interface nsIFastLoadFileControl : nsISupports
-{
-    /**
-     * Get and set the recorded checksum value from the FastLoad file header.
-     */
-    attribute PRUint32 checksum;
-
-    /**
-     * Multiplexed document control methods.  A FastLoad file may contain
-     * multiple interleaved documents identified by a URI specifier string,
-     * and indexed for fast multiplexor select by an opaque URI object key.
-     * You StartMuxedDocument when initiating a document load, then Select
-     * before every batch of calls to (de)serialize document data, and End
-     * when the load completes.
-     *
-     * Document multiplexing is necessary to support incremental FastLoad
-     * development in a non-blocking i/o architecture such as Mozilla, where
-     * some (but not all, at first, or for a while during development) of the
-     * results of parsing and compiling various inputs can be multiplexed to
-     * or from a FastLoad file.
-     *
-     * Note: Select returns the previously selected URI object in case the
-     * caller is synchronously selecting and writing data to the FastLoad
-     * file, so the caller can reselect the previous URI and return to code
-     * the continues to write FastLoad data for the previous URI, unaware of
-     * the nested select/write/reselect.
-     */
-    void        startMuxedDocument(in nsISupports aURI, in string aURISpec);
-    nsISupports selectMuxedDocument(in nsISupports aURI);
-    void        endMuxedDocument(in nsISupports aURI);
-
-    /**
-     * Return true if aURISpec identifies a muxed document in the FastLoad
-     * file, false otherwise.
-     */
-    boolean     hasMuxedDocument(in string aURISpec);
-};
-
-[scriptable, uuid(652ecec6-d40b-45b6-afef-641d6c63a35b)]
-interface nsIFastLoadReadControl : nsIFastLoadFileControl
-{
-    /**
-     * Computes the correct checksum of the FastLoad file, independent of the
-     * header's checksum value.  The header checksum field is treated as zero
-     * when computing the checksum.
-     */
-    PRUint32 computeChecksum();
-
-    /**
-     * Get the collection of dependency nsIFile instances recorded during the
-     * FastLoad file write or read/update process, and checked during the read
-     * process to invalidate the FastLoad file if any dependencies are newer.
-     */
-    readonly attribute nsISimpleEnumerator dependencies;
-};
-
-[scriptable, uuid(2ad6e9e6-1379-4e45-a899-a54b27ff915c)]
-interface nsIFastLoadWriteControl : nsIFastLoadFileControl
-{
-    /**
-     * Add a file dependency of the FastLoad file (e.g., a .jar file) to the
-     * set of dependencies that trigger regeneration if any dependency has a
-     * last-modified-time greater than the FastLoad file's mtime.
-     */
-    void addDependency(in nsIFile aFile);
-};
Index: trunk/src/libs/xpcom18a4/xpcom/io/nsIFastLoadService.idl
===================================================================
--- trunk/src/libs/xpcom18a4/xpcom/io/nsIFastLoadService.idl	(revision 101807)
+++ 	(revision )
@@ -1,155 +1,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * 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/
- *
- * 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.
- *
- * The Original Code is Mozilla FastLoad code.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2001
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Brendan Eich <brendan@mozilla.org> (original author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of 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 ***** */
-
-#include "nsISupports.idl"
-#include "nsrootidl.idl"
-
-interface nsIFastLoadReadControl;
-interface nsIFile;
-interface nsIInputStream;
-interface nsIOutputStream;
-interface nsIObjectInputStream;
-interface nsIObjectOutputStream;
-
-[scriptable, uuid(715577db-d9c5-464a-a32e-0a40c29b22d4)]
-interface nsIFastLoadFileIO : nsISupports
-{
-    readonly attribute nsIInputStream  inputStream;
-    readonly attribute nsIOutputStream outputStream;
-};
-
-[scriptable, uuid(759e475e-0c23-4dbf-b1b8-78c9369e3072)]
-interface nsIFastLoadService : nsISupports
-{
-    nsIFile newFastLoadFile(in string aBaseName);
-
-    nsIObjectInputStream  newInputStream(in nsIInputStream aSrcStream);
-    nsIObjectOutputStream newOutputStream(in nsIOutputStream aDestStream);
-
-    // Flag values for the direction attribute and the aDirectionFlags
-    // parameter to startMuxedDocument.
-    const PRInt32 NS_FASTLOAD_READ = 1;
-    const PRInt32 NS_FASTLOAD_WRITE = 2;
-
-    attribute nsIObjectInputStream  inputStream;
-    attribute nsIObjectOutputStream outputStream;
-    attribute nsIFastLoadFileIO     fileIO;
-    readonly attribute PRInt32      direction;
-
-    /**
-     * These methods associate a URI object with its spec, for faster select
-     * using the object pointer as a key, rather than the spec string.  The
-     * selectMuxedDocument method returns the previously selected URI object,
-     * in case a caller needs to reselect the previous after muxing data for
-     * a given URI synchronously.  For the non-blocking or "asynchronous" i/o
-     * case, the caller must select the source URI from the FastLoad multiplex
-     * before writing a new burst of data parsed from the slow-loaded source.
-     *
-     * Clients of inputStream and outputStream should try to demultiplex data
-     * from the input stream only if fastLoadService->StartMuxedDocument(uri,
-     * urispec, NS_FASTLOAD_READ) succeeds.  If StartMuxedDocument fails with
-     * NS_ERROR_NOT_AVAILABLE, callers should slow-load the documents, muxing
-     * their data to the current output stream.
-     */
-    void        startMuxedDocument(in nsISupports aURI,
-                                   in string aURISpec,
-                                   in PRInt32 aDirectionFlags);
-    nsISupports selectMuxedDocument(in nsISupports aURI);
-    void        endMuxedDocument(in nsISupports aURI);
-
-    void        addDependency(in nsIFile aFile);
-
-    PRUint32    computeChecksum(in nsIFile aFile,
-                                in nsIFastLoadReadControl aControl);
-    void        cacheChecksum(in nsIFile aFile,
-                              in nsIObjectOutputStream aStream);
-
-    [noscript] void getFastLoadReferent(inout nsISupports aPtr);
-
-    [noscript] void readFastLoadPtr(in nsIObjectInputStream aInputStream,
-                                    inout nsISupports aPtr);
-
-    [noscript] void writeFastLoadPtr(in nsIObjectOutputStream aOutputStream,
-                                     in nsISupports aPtr);
-
-    /**
-     * Return true if aURISpec identifies a muxed document in the FastLoad
-     * file, false otherwise.
-     */
-    boolean     hasMuxedDocument(in string aURISpec);
-};
-
-%{C++
-#define NS_FASTLOADSERVICE_CLASSNAME "Mozilla FastLoad Service"
-
-#define NS_FASTLOADSERVICE_CID \
-    {0xc943093c,0xac94,0x4bee,{0x84,0x0b,0x8b,0x5a,0x6e,0x31,0x4f,0xa7}}
-
-#define NS_FASTLOADSERVICE_CONTRACTID \
-    "@mozilla.org/fast-load-service;1"
-
-#ifndef nsCOMPtr_h___
-# include "nsCOMPtr.h"
-#endif
-#ifndef __gen_nsIFile_h__
-# include "nsIFile.h"
-#endif
-#ifndef nsIServiceManager_h___
-# include "nsIServiceManager.h"
-#endif
-
-inline const nsGetServiceByCID
-do_GetFastLoadService(nsresult *aResultCode = 0)
-{
-    static NS_DEFINE_CID(kFastLoadServiceCID, NS_FASTLOADSERVICE_CID);
-    return nsGetServiceByCID(kFastLoadServiceCID, nsnull, aResultCode);
-}
-
-inline nsresult
-NS_AddFastLoadDependency(nsIFile* aFile)
-{
-    nsCOMPtr<nsIFastLoadService> fastLoadService(do_GetFastLoadService());
-    if (fastLoadService) {
-        nsresult rv = fastLoadService->AddDependency(aFile);
-        if (NS_FAILED(rv) && rv != NS_ERROR_NOT_AVAILABLE)
-            return rv;
-    }
-    return NS_OK;
-}
-
-%}
