Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | Static Private Member Functions
nsFastLoadFileWriter Class Reference

Inherit from the concrete class nsBinaryInputStream, which inherits from abstract nsIObjectInputStream but does not implement its direct methods. More...

#include <nsFastLoadFile.h>

Inheritance diagram for nsFastLoadFileWriter:
Inheritance graph
[legend]
Collaboration diagram for nsFastLoadFileWriter:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsFastLoadFileWriter (nsIOutputStream *aStream, nsIFastLoadFileIO *aFileIO)
virtual ~nsFastLoadFileWriter ()
void writeObject (in nsISupports aObject, in PRBool aIsStrongRef)
 Write the object whose "root" or XPCOM-identity nsISupports is aObject.
void writeSingleRefObject (in nsISupports aObject)
 Write an object referenced singly and strongly via its root nsISupports or a subclass of its root nsISupports.
void writeCompoundObject (in nsISupports aObject, in nsIIDRef aIID, in PRBool aIsStrongRef)
 Write the object referenced by an interface pointer at aObject that inherits from a non-primary nsISupports, i.e., a reference to one of the multiply inherited interfaces derived from an nsISupports other than the root or XPCOM-identity nsISupports; or a reference to an inner object in the case of true XPCOM aggregation.
void writeID (in nsIDRef aID)
charPtr getBuffer (in PRUint32 aLength, in PRUint32 aAlignMask)
 Optimized serialization support -- see nsIStreamBufferAccess.idl.
void putBuffer (in charPtr aBuffer, in PRUint32 aLength)
void setOutputStream (in nsIOutputStream aOutputStream)
void writeBoolean (in PRBool aBoolean)
void write8 (in PRUint8 aByte)
void write16 (in PRUint16 a16)
void write32 (in PRUint32 a32)
void write64 (in PRUint64 a64)
void writeFloat (in float aFloat)
void writeDouble (in double aDouble)
void writeStringZ (in string aString)
 Write a NUL-terminated 8-bit char* string to a binary stream.
void writeWStringZ (in wstring aString)
 Write a NUL-terminated 16-bit PRUnichar* string to a binary stream.
void writeUtf8Z (in wstring aString)
 Write a NUL-terminated UTF8-encoded string to a binary stream, produced from a NUL-terminated 16-bit PRUnichar* string argument.
void writeBytes ([size_is(aLength)] in string aString, in PRUint32 aLength)
 Write an opaque byte array to a binary stream.
void writeByteArray ([array, size_is(aLength)] in PRUint8 aBytes, in PRUint32 aLength)
 Write an opaque byte array to a binary stream.
void close ()
 Close the stream.
void flush ()
 Flush the stream.
unsigned long write (in string aBuf, in unsigned long aCount)
 Write data into the stream.
unsigned long writeFrom (in nsIInputStream aFromStream, in unsigned long aCount)
 Writes data into the stream from an input stream.
unsigned long writeSegments (in nsReadSegmentFun aReader, in voidPtr aClosure, in unsigned long aCount)
 Low-level write method that has access to the stream's underlying buffer.
boolean isNonBlocking ()
void addDependency (in nsIFile aFile)
 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 startMuxedDocument (in nsISupports aURI, in string aURISpec)
 Multiplexed document control methods.
nsISupports selectMuxedDocument (in nsISupports aURI)
void endMuxedDocument (in nsISupports aURI)
boolean hasMuxedDocument (in string aURISpec)
 Return true if aURISpec identifies a muxed document in the FastLoad file, false otherwise.
void seek (in long whence, in long long offset)
 seek
long long tell ()
 tell
void setEOF ()
 setEOF

Public Attributes

attribute PRUint32 checksum
 Get and set the recorded checksum value from the FastLoad file header.
const PRInt32 NS_SEEK_SET = 0
const PRInt32 NS_SEEK_CUR = 1
const PRInt32 NS_SEEK_END = 2

Protected Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIOUTPUTSTREAM
NS_DECL_NSIBINARYOUTPUTSTREAM
NS_DECL_NSIOBJECTOUTPUTSTREAM
nsresult 
WriteFully (const char *aBuf, PRUint32 aCount)

Protected Attributes

nsCOMPtr< nsISeekableStreammSeekableOutput
nsFastLoadHeader mHeader
PLDHashTable mIDMap
PLDHashTable mObjectMap
PLDHashTable mDocumentMap
PLDHashTable mURIMap
PLDHashTable mDependencyMap
nsDocumentMapWriteEntrymCurrentDocumentMapEntry
nsCOMPtr< nsIFastLoadFileIOmFileIO
nsCOMPtr< nsIOutputStreammOutputStream
nsCOMPtr< nsIStreamBufferAccessmBufferAccess

Private Member Functions

NS_DECL_ISUPPORTS_INHERITED
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)
NS_IMETHOD SetOutputStream (nsIOutputStream *aOutputStream)
NS_DECL_NSIFASTLOADFILECONTROL
NS_DECL_NSIFASTLOADWRITECONTROL
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 Private Member Functions

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)

Detailed Description

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.

Definition at line 412 of file nsFastLoadFile.h.


Constructor & Destructor Documentation

Definition at line 418 of file nsFastLoadFile.h.

Here is the call graph for this function:

virtual nsFastLoadFileWriter::~nsFastLoadFileWriter ( ) [inline, virtual]

Member Function Documentation

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 nsIOutputStream::close ( ) [inherited]

Close the stream.

Forces the output stream to flush any buffered data.

Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif unable to flush without blocking the calling thread (non-blocking mode only)

Reimplemented in nsFastLoadFileUpdater.

Definition at line 1943 of file nsFastLoadFile.cpp.

{
    nsresult rv;

    memcpy(mHeader.mMagic, magic, MFL_FILE_MAGIC_SIZE);
    mHeader.mChecksum = 0;
    mHeader.mVersion = MFL_FILE_VERSION;

    PRInt64 footerOffset;
    rv = mSeekableOutput->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 = mSeekableOutput->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 = mSeekableOutput->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 = mSeekableOutput->Tell(&fileSize);
    LL_L2UI(mHeader.mFileSize, fileSize);
    if (NS_FAILED(rv))
        return rv;

    rv = mSeekableOutput->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<nsIOutputStream> output;
        rv = mBufferAccess->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.
        nsCOMPtr<nsIStreamBufferAccess> 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.
        nsCOMPtr<nsISeekableStream> 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();
}

Here is the call graph for this function:

PLDHashOperator PR_CALLBACK nsFastLoadFileWriter::DependencyMapEnumerate ( PLDHashTable aTable,
PLDHashEntryHdr aHdr,
PRUint32  aNumber,
void aData 
) [static, private]

Definition at line 1805 of file nsFastLoadFile.cpp.

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

Here is the call graph for this function:

Here is the caller graph for this function:

PLDHashOperator PR_CALLBACK nsFastLoadFileWriter::DocumentMapEnumerate ( PLDHashTable aTable,
PLDHashEntryHdr aHdr,
PRUint32  aNumber,
void aData 
) [static, private]

Definition at line 1785 of file nsFastLoadFile.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIFastLoadFileControl::endMuxedDocument ( in nsISupports  aURI) [inherited]
void nsIOutputStream::flush ( ) [inherited]

Flush the stream.

Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif unable to flush without blocking the calling thread (non-blocking mode only)
charPtr nsIObjectOutputStream::getBuffer ( in PRUint32  aLength,
in PRUint32  aAlignMask 
) [inherited]

Optimized serialization support -- see nsIStreamBufferAccess.idl.

Return true if aURISpec identifies a muxed document in the FastLoad file, false otherwise.

PLDHashOperator PR_CALLBACK nsFastLoadFileWriter::IDMapEnumerate ( PLDHashTable aTable,
PLDHashEntryHdr aHdr,
PRUint32  aNumber,
void aData 
) [static, private]

Definition at line 1741 of file nsFastLoadFile.cpp.

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

Here is the caller graph for this function:

Definition at line 1893 of file nsFastLoadFile.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Returns:
true if stream is non-blocking

NOTE: writing to a blocking output stream will block the calling thread until all given data can be consumed by the stream.

nsresult nsFastLoadFileWriter::MapID ( const nsID aSlowID,
NSFastLoadID aResult 
) [private]

Definition at line 1293 of file nsFastLoadFile.cpp.

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

Here is the call graph for this function:

Here is the caller graph for this function:

PLDHashOperator PR_CALLBACK nsFastLoadFileWriter::ObjectMapEnumerate ( PLDHashTable aTable,
PLDHashEntryHdr aHdr,
PRUint32  aNumber,
void aData 
) [static, private]

Definition at line 1761 of file nsFastLoadFile.cpp.

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

Here is the caller graph for this function:

Definition at line 1930 of file nsFastLoadFile.cpp.

{
    nsresult rv;

    rv = mSeekableOutput->Seek(nsISeekableStream::NS_SEEK_SET,
                               sizeof(nsFastLoadHeader));
    if (NS_FAILED(rv))
        return rv;

    return Init();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIObjectOutputStream::putBuffer ( in charPtr  aBuffer,
in PRUint32  aLength 
) [inherited]
void nsISeekableStream::seek ( in long  whence,
in long long  offset 
) [inherited]

seek

This method moves the stream offset of the steam implementing this interface.

Parameters:
whencespecifies how to interpret the 'offset' parameter in setting the stream offset associated with the implementing stream.
offsetspecifies a value, in bytes, that is used in conjunction with the 'whence' parameter to set the stream offset of the implementing stream. A negative value causes seeking in the reverse direction.
nsISupports nsIFastLoadFileControl::selectMuxedDocument ( in nsISupports  aURI) [inherited]

setEOF

This method truncates the stream at the current offset.

Definition at line 2303 of file nsFastLoadFile.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIFastLoadFileControl::startMuxedDocument ( in nsISupports  aURI,
in string  aURISpec 
) [inherited]

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.

tell

This method reports the current offset, in bytes, from the start of the stream.

unsigned long nsIOutputStream::write ( in string  aBuf,
in unsigned long  aCount 
) [inherited]

Write data into the stream.

Parameters:
aBufthe buffer containing the data to be written
aCountthe maximum number of bytes to be written
Returns:
number of bytes written (may be less than aCount)
Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif writing to the output stream would block the calling thread (non-blocking mode only)
<other-error>on failure
void nsIBinaryOutputStream::write8 ( in PRUint8  aByte) [inherited]
void nsIBinaryOutputStream::writeByteArray ( [array, size_is(aLength)] in PRUint8  aBytes,
in PRUint32  aLength 
) [inherited]

Write an opaque byte array to a binary stream.

void nsIBinaryOutputStream::writeBytes ( [size_is(aLength)] in string  aString,
in PRUint32  aLength 
) [inherited]

Write an opaque byte array to a binary stream.

void nsIObjectOutputStream::writeCompoundObject ( in nsISupports  aObject,
in nsIIDRef  aIID,
in PRBool  aIsStrongRef 
) [inherited]

Write the object referenced by an interface pointer at aObject that inherits from a non-primary nsISupports, i.e., a reference to one of the multiply inherited interfaces derived from an nsISupports other than the root or XPCOM-identity nsISupports; or a reference to an inner object in the case of true XPCOM aggregation.

aIID identifies this interface.

NS_IMETHODIMP nsFastLoadFileWriter::WriteCompoundObject ( nsISupports *  aObject,
const nsIID aIID,
PRBool  aIsStrongRef 
) [private]

Definition at line 2238 of file nsFastLoadFile.cpp.

{
    nsresult rv;
    nsCOMPtr<nsISupports> rootObject(do_QueryInterface(aObject));
    
    // We could assert that |rootObject != aObject|, but that would prevent
    // callers who don't know whether they're dealing with the primary
    // nsISupports pointer (e.g., they don't know which implementation of
    // nsIURI they have) from using this function.

#ifdef NS_DEBUG
    nsCOMPtr<nsISupports> roundtrip;
    rootObject->QueryInterface(aIID, getter_AddRefs(roundtrip));
    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);
}

Here is the call graph for this function:

void nsIBinaryOutputStream::writeDouble ( in double  aDouble) [inherited]

Definition at line 1696 of file nsFastLoadFile.cpp.

{
    return Write32(aID ^ MFL_ID_XOR_KEY);
}

Here is the caller graph for this function:

void nsIBinaryOutputStream::writeFloat ( in float  aFloat) [inherited]

Definition at line 1823 of file nsFastLoadFile.cpp.

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

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1644 of file nsFastLoadFile.cpp.

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

Here is the caller graph for this function:

unsigned long nsIOutputStream::writeFrom ( in nsIInputStream  aFromStream,
in unsigned long  aCount 
) [inherited]

Writes data into the stream from an input stream.

Parameters:
aFromStreamthe stream containing the data to be written
aCountthe maximum number of bytes to be written
Returns:
number of bytes written (may be less than aCount)
Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif writing to the output stream would block the calling thread (non-blocking mode only)
<other-error>on failure

NOTE: This method is defined by this interface in order to allow the output stream to efficiently copy the data from the input stream into its internal buffer (if any). If this method was provided as an external facility, a separate char* buffer would need to be used in order to call the output stream's other Write method.

nsresult nsBinaryOutputStream::WriteFully ( const char *  aBuf,
PRUint32  aCount 
) [protected, inherited]

Definition at line 97 of file nsBinaryStream.cpp.

{
    nsresult rv;
    PRUint32 bytesWritten;

    rv = mOutputStream->Write(aBuf, aCount, &bytesWritten);
    if (NS_FAILED(rv)) return rv;
    if (bytesWritten != aCount)
        return NS_ERROR_FAILURE;
    return NS_OK;
}

Definition at line 1311 of file nsFastLoadFile.cpp.

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

Here is the caller graph for this function:

void nsIObjectOutputStream::writeID ( in nsIDRef  aID) [inherited]

Definition at line 2271 of file nsFastLoadFile.cpp.

{
    nsresult rv;
    NSFastLoadID fastID;

    rv = MapID(aID, &fastID);
    if (NS_FAILED(rv))
        return rv;

    return WriteFastID(fastID);
}

Here is the call graph for this function:

Definition at line 1725 of file nsFastLoadFile.cpp.

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

Here is the caller graph for this function:

void nsIObjectOutputStream::writeObject ( in nsISupports  aObject,
in PRBool  aIsStrongRef 
) [inherited]

Write the object whose "root" or XPCOM-identity nsISupports is aObject.

The cause for writing this object is a strong or weak reference, so the aIsStrongRef argument must tell which kind of pointer is being followed here during serialization.

If the object has only one strong reference in the serialization and no weak refs, use writeSingleRefObject. This is a valuable optimization: it saves space in the stream, and cycles on both ends of the process.

If the reference being serialized is a pointer to an interface not on the primary inheritance chain ending in the root nsISupports, you must call writeCompoundObject instead of this method.

NS_IMETHODIMP nsFastLoadFileWriter::WriteObject ( nsISupports *  aObject,
PRBool  aIsStrongRef 
) [private]

Definition at line 2212 of file nsFastLoadFile.cpp.

{
#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);
}

Here is the call graph for this function:

nsresult nsFastLoadFileWriter::WriteObjectCommon ( nsISupports *  aObject,
PRBool  aIsStrongRef,
PRUint32  aQITag 
) [private]

Definition at line 2084 of file nsFastLoadFile.cpp.

{
    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) {
                NS_NOTREACHED("aObject must implement nsIClassInfo");
                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) {
            NS_NOTREACHED("aObject must implement nsISerializable");
            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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

unsigned long nsIOutputStream::writeSegments ( in nsReadSegmentFun  aReader,
in voidPtr  aClosure,
in unsigned long  aCount 
) [inherited]

Low-level write method that has access to the stream's underlying buffer.

The reader function may be called multiple times for segmented buffers. WriteSegments is expected to keep calling the reader until either there is nothing left to write or the reader returns an error. WriteSegments should not call the reader with zero bytes to provide.

Parameters:
aReaderthe "provider" of the data to be written
aClosureopaque parameter passed to reader
aCountthe maximum number of bytes to be written
Returns:
number of bytes written (may be less than aCount)
Exceptions:
NS_BASE_STREAM_WOULD_BLOCKif writing to the output stream would block the calling thread (non-blocking mode only)
<other-error>on failure

NOTE: this function may be unimplemented if a stream has no underlying buffer (e.g., socket output stream).

Definition at line 1702 of file nsFastLoadFile.cpp.

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

Here is the caller graph for this function:

void nsIObjectOutputStream::writeSingleRefObject ( in nsISupports  aObject) [inherited]

Write an object referenced singly and strongly via its root nsISupports or a subclass of its root nsISupports.

There must not be other refs to aObject in memory, or in the serialization.

NS_IMETHODIMP nsFastLoadFileWriter::WriteSingleRefObject ( nsISupports *  aObject) [private]

Definition at line 2225 of file nsFastLoadFile.cpp.

{
#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);
}

Here is the call graph for this function:

Definition at line 1668 of file nsFastLoadFile.cpp.

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

Here is the caller graph for this function:

Write a NUL-terminated 8-bit char* string to a binary stream.

void nsIBinaryOutputStream::writeUtf8Z ( in wstring  aString) [inherited]

Write a NUL-terminated UTF8-encoded string to a binary stream, produced from a NUL-terminated 16-bit PRUnichar* string argument.

void nsIBinaryOutputStream::writeWStringZ ( in wstring  aString) [inherited]

Write a NUL-terminated 16-bit PRUnichar* string to a binary stream.


Member Data Documentation

Get and set the recorded checksum value from the FastLoad file header.

Definition at line 63 of file nsIFastLoadFileControl.idl.

Definition at line 85 of file nsBinaryStream.h.

Definition at line 522 of file nsFastLoadFile.h.

Definition at line 520 of file nsFastLoadFile.h.

Definition at line 518 of file nsFastLoadFile.h.

Definition at line 523 of file nsFastLoadFile.h.

Definition at line 514 of file nsFastLoadFile.h.

Definition at line 516 of file nsFastLoadFile.h.

Definition at line 517 of file nsFastLoadFile.h.

Definition at line 84 of file nsBinaryStream.h.

Definition at line 512 of file nsFastLoadFile.h.

Definition at line 519 of file nsFastLoadFile.h.

Definition at line 62 of file nsISeekableStream.idl.

Definition at line 68 of file nsISeekableStream.idl.

Definition at line 56 of file nsISeekableStream.idl.


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