Back to index

lightning-sunbird  0.9+nobinonly
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes
nsInputStreamPump Class Reference

#include <nsInputStreamPump.h>

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

List of all members.

Public Types

typedef void(* PeekSegmentFun )(void *closure, const PRUint8 *buf, PRUint32 bufLen)

Public Member Functions

NS_DECL_ISUPPORTS
NS_DECL_NSIREQUEST
NS_DECL_NSIINPUTSTREAMPUMP
NS_DECL_NSIINPUTSTREAMCALLBACK 
nsInputStreamPump ()
 ~nsInputStreamPump ()
 NS_HIDDEN_ (void) PeekStream(PeekSegmentFun callback
 Peek into the first chunk of data that's in the stream.
void init (in nsIInputStream aStream, in long long aStreamPos, in long long aStreamLen, in unsigned long aSegmentSize, in unsigned long aSegmentCount, in boolean aCloseWhenDone)
 Initialize the input stream pump.
void asyncRead (in nsIStreamListener aListener, in nsISupports aListenerContext)
 asyncRead causes the input stream to be read in chunks and delivered asynchronously to the listener via OnDataAvailable.
boolean isPending ()
 Indicates whether the request is pending.
void cancel (in nsresult aStatus)
 Cancels the current request.
void suspend ()
 Suspends the current request.
void resume ()
 Resumes the current request.
void onInputStreamReady (in nsIAsyncInputStream aStream)
 Called to indicate that the stream is either readable or closed.

Static Public Member Functions

static NS_HIDDEN_ (nsresult) Create(nsInputStreamPump **result

Public Attributes

static nsIInputStreamstream
static nsIInputStream PRInt64 streamPos = -1
static nsIInputStream PRInt64
PRInt64 
streamLen = -1
static nsIInputStream PRInt64
PRInt64 PRUint32 
segsize = 0
static nsIInputStream PRInt64
PRInt64 PRUint32 PRUint32 
segcount = 0
static nsIInputStream PRInt64
PRInt64 PRUint32 PRUint32
PRBool 
closeWhenDone = PR_FALSE)
voidclosure
readonly attribute AUTF8String name
 The name of the request.
readonly attribute nsresult status
 The error status associated with the request.
attribute nsILoadGroup loadGroup
 The load group of this request.
attribute nsLoadFlags loadFlags
 The load flags of this request.
const unsigned long LOAD_NORMAL = 0
 No special load flags:
const unsigned long LOAD_BACKGROUND = 1 << 0
 Don't deliver status notifications to the nsIProgressEventSink, or keep this load from completing the nsILoadGroup it may belong to.
const unsigned long INHIBIT_CACHING = 1 << 7
 This flag prevents caching of any kind.
const unsigned long INHIBIT_PERSISTENT_CACHING = 1 << 8
 This flag prevents caching on disk (or other persistent media), which may be needed to preserve privacy.
const unsigned long LOAD_BYPASS_CACHE = 1 << 9
 Force an end-to-end download of content data from the origin server.
const unsigned long LOAD_FROM_CACHE = 1 << 10
 Load from the cache, bypassing protocol specific validation logic.
const unsigned long VALIDATE_ALWAYS = 1 << 11
 The following flags control the frequency of cached content validation when neither LOAD_BYPASS_CACHE or LOAD_FROM_CACHE are set.
const unsigned long VALIDATE_NEVER = 1 << 12
const unsigned long VALIDATE_ONCE_PER_SESSION = 1 << 13

Protected Types

enum  { STATE_IDLE, STATE_START, STATE_TRANSFER, STATE_STOP }

Protected Member Functions

nsresult EnsureWaiting ()
PRUint32 OnStateStart ()
PRUint32 OnStateTransfer ()
PRUint32 OnStateStop ()

Protected Attributes

PRUint32 mState
nsCOMPtr< nsILoadGroupmLoadGroup
nsCOMPtr< nsIStreamListenermListener
nsCOMPtr< nsISupports > mListenerContext
nsCOMPtr< nsIEventQueuemEventQ
nsCOMPtr< nsIInputStreammStream
nsCOMPtr< nsIAsyncInputStreammAsyncStream
nsUint64 mStreamOffset
nsUint64 mStreamLength
PRUint32 mSegSize
PRUint32 mSegCount
nsresult mStatus
PRUint32 mSuspendCount
PRUint32 mLoadFlags
PRPackedBool mIsPending
PRPackedBool mWaiting
PRPackedBool mCloseWhenDone

Detailed Description

Definition at line 53 of file nsInputStreamPump.h.


Member Typedef Documentation

Definition at line 74 of file nsInputStreamPump.h.


Member Enumeration Documentation

anonymous enum [protected]
Enumerator:
STATE_IDLE 
STATE_START 
STATE_TRANSFER 
STATE_STOP 

Definition at line 90 of file nsInputStreamPump.h.


Constructor & Destructor Documentation

Definition at line 66 of file nsInputStreamPump.cpp.

    : mState(STATE_IDLE)
    , mStreamOffset(0)
    , mStreamLength(LL_MaxUint())
    , mStatus(NS_OK)
    , mSuspendCount(0)
    , mLoadFlags(LOAD_NORMAL)
    , mWaiting(PR_FALSE)
    , mCloseWhenDone(PR_FALSE)
{
#if defined(PR_LOGGING)
    if (!gStreamPumpLog)
        gStreamPumpLog = PR_NewLogModule("nsStreamPump");
#endif
}

Definition at line 82 of file nsInputStreamPump.cpp.

{
}

Member Function Documentation

void nsIInputStreamPump::asyncRead ( in nsIStreamListener  aListener,
in nsISupports  aListenerContext 
) [inherited]

asyncRead causes the input stream to be read in chunks and delivered asynchronously to the listener via OnDataAvailable.

Parameters:
aListenerreceives notifications.
aListenerContextpassed to listener methods.
void nsIRequest::cancel ( in nsresult  aStatus) [inherited]

Cancels the current request.

This will close any open input or output streams and terminate any async requests. Users should normally pass NS_BINDING_ABORTED, although other errors may also be passed. The error passed in will become the value of the status attribute.

Parameters:
aStatusthe reason for canceling this request.

NOTE: most nsIRequest implementations expect aStatus to be a failure code; however, some implementations may allow aStatus to be a success code such as NS_OK. In general, aStatus should be a failure code.

Definition at line 143 of file nsInputStreamPump.cpp.

{
    // no need to worry about multiple threads... an input stream pump lives
    // on only one thread.

    if (!mWaiting) {
        nsresult rv = mAsyncStream->AsyncWait(this, 0, 0, mEventQ);
        if (NS_FAILED(rv)) {
            NS_ERROR("AsyncWait failed");
            return rv;
        }
        mWaiting = PR_TRUE;
    }
    return NS_OK;
}
void nsIInputStreamPump::init ( in nsIInputStream  aStream,
in long long  aStreamPos,
in long long  aStreamLen,
in unsigned long  aSegmentSize,
in unsigned long  aSegmentCount,
in boolean  aCloseWhenDone 
) [inherited]

Initialize the input stream pump.

Parameters:
aStreamcontains the data to be read. if the input stream is non-blocking, then it will be QI'd to nsIAsyncInputStream. if the QI succeeds then the stream will be read directly. otherwise, it will be read on a background thread using the stream transport service.
aStreamPosspecifies the stream offset from which to start reading. the offset value is absolute. pass -1 to specify the current offset. NOTE: this parameter is ignored if the underlying stream does not implement nsISeekableStream.
aStreamLenspecifies how much data to read from the stream. pass -1 to read all data available in the stream.
aSegmentSizeif the stream transport service is used, then this parameter specifies the segment size for the stream transport's buffer. pass 0 to specify the default value.
aSegmentCountif the stream transport service is used, then this parameter specifies the segment count for the stream transport's buffer. pass 0 to specify the default value.
aCloseWhenDoneif true, the input stream will be closed after it has been read.
boolean nsIRequest::isPending ( ) [inherited]

Indicates whether the request is pending.

nsIRequest::isPending is true when there is an outstanding asynchronous event that will make the request no longer be pending. Requests do not necessarily start out pending; in some cases, requests have to be explicitly initiated (e.g. nsIChannel implementations are only pending once asyncOpen returns successfully).

Requests can become pending multiple times during their lifetime.

Returns:
TRUE if the request has yet to reach completion.
FALSE if the request has reached completion (e.g., after OnStopRequest has fired).
Note:
Suspended requests are still considered pending.
static nsInputStreamPump::NS_HIDDEN_ ( nsresult  ) [static]

Peek into the first chunk of data that's in the stream.

Note that this method will not call the callback when there is no data in the stream. The callback will be called at most once.

The data from the stream will not be consumed, i.e. the pump's listener can still read all the data.

Do not call before asyncRead. Do not call after onStopRequest.

Called to indicate that the stream is either readable or closed.

Parameters:
aStreamThe stream whose asyncWait method was called.

Definition at line 422 of file nsInputStreamPump.cpp.

{
    LOG(("  OnStateStart [this=%x]\n", this));

    nsresult rv;

    // need to check the reason why the stream is ready.  this is required
    // so our listener can check our status from OnStartRequest.
    // XXX async streams should have a GetStatus method!
    if (NS_SUCCEEDED(mStatus)) {
        PRUint32 avail;
        rv = mAsyncStream->Available(&avail);
        if (NS_FAILED(rv) && rv != NS_BASE_STREAM_CLOSED)
            mStatus = rv;
    }

    rv = mListener->OnStartRequest(this, mListenerContext);

    // an error returned from OnStartRequest should cause us to abort; however,
    // we must not stomp on mStatus if already canceled.
    if (NS_FAILED(rv) && NS_SUCCEEDED(mStatus))
        mStatus = rv;

    return NS_SUCCEEDED(mStatus) ? STATE_TRANSFER : STATE_STOP;
}

Definition at line 546 of file nsInputStreamPump.cpp.

{
    LOG(("  OnStateStop [this=%x status=%x]\n", this, mStatus));

    // if an error occured, we must be sure to pass the error onto the async
    // stream.  in some cases, this is redundant, but since close is idempotent,
    // this is OK.  otherwise, be sure to honor the "close-when-done" option.

    if (NS_FAILED(mStatus))
        mAsyncStream->CloseWithStatus(mStatus);
    else if (mCloseWhenDone)
        mAsyncStream->Close();

    mAsyncStream = 0;
    mEventQ = 0;
    mIsPending = PR_FALSE;

    mListener->OnStopRequest(this, mListenerContext, mStatus);
    mListener = 0;
    mListenerContext = 0;

    if (mLoadGroup)
        mLoadGroup->RemoveRequest(this, nsnull, mStatus);

    return STATE_IDLE;
}

Definition at line 449 of file nsInputStreamPump.cpp.

{
    LOG(("  OnStateTransfer [this=%x]\n", this));

    // if canceled, go directly to STATE_STOP...
    if (NS_FAILED(mStatus))
        return STATE_STOP;

    nsresult rv;

    PRUint32 avail;
    rv = mAsyncStream->Available(&avail);
    LOG(("  Available returned [stream=%x rv=%x avail=%u]\n", mAsyncStream.get(), rv, avail));

    if (rv == NS_BASE_STREAM_CLOSED) {
        rv = NS_OK;
        avail = 0;
    }
    else if (NS_SUCCEEDED(rv) && avail) {
        // figure out how much data to report (XXX detect overflow??)
        if (nsUint64(avail) + mStreamOffset > mStreamLength)
            avail = mStreamLength - mStreamOffset;

        if (avail) {
            // we used to limit avail to 16K - we were afraid some ODA handlers
            // might assume they wouldn't get more than 16K at once
            // we're removing that limit since it speeds up local file access.
            // Now there's an implicit 64K limit of 4 16K segments
            // NOTE: ok, so the story is as follows.  OnDataAvailable impls
            //       are by contract supposed to consume exactly |avail| bytes.
            //       however, many do not... mailnews... stream converters...
            //       cough, cough.  the input stream pump is fairly tolerant
            //       in this regard; however, if an ODA does not consume any
            //       data from the stream, then we could potentially end up in
            //       an infinite loop.  we do our best here to try to catch
            //       such an error.  (see bug 189672)

            // in most cases this QI will succeed (mAsyncStream is almost always
            // a nsPipeInputStream, which implements nsISeekableStream::Tell).
            PRInt64 offsetBefore;
            nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mAsyncStream);
            if (seekable)
                seekable->Tell(&offsetBefore);

            LOG(("  calling OnDataAvailable [offset=%lld count=%u]\n", PRUint64(mStreamOffset), avail));
            rv = mListener->OnDataAvailable(this, mListenerContext, mAsyncStream, mStreamOffset, avail);

            // don't enter this code if ODA failed or called Cancel
            if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(mStatus)) {
                // test to see if this ODA failed to consume data
                if (seekable) {
                    PRInt64 offsetAfter;
                    seekable->Tell(&offsetAfter);
                    nsUint64 offsetBefore64 = PRUint64(offsetBefore);
                    nsUint64 offsetAfter64 = PRUint64(offsetAfter);
                    if (offsetAfter64 > offsetBefore64) {
                        nsUint64 offsetDelta = offsetAfter64 - offsetBefore64;
                        mStreamOffset += offsetDelta;
                    }
                    else if (mSuspendCount == 0) {
                        //
                        // possible infinite loop if we continue pumping data!
                        //
                        // NOTE: although not allowed by nsIStreamListener, we
                        // will allow the ODA impl to Suspend the pump.  IMAP
                        // does this :-(
                        //
                        NS_ERROR("OnDataAvailable implementation consumed no data");
                        mStatus = NS_ERROR_UNEXPECTED;
                    }
                }
                else
                    mStreamOffset += avail; // assume ODA behaved well
            }
        }
    }

    // an error returned from Available or OnDataAvailable should cause us to
    // abort; however, we must not stomp on mStatus if already canceled.

    if (NS_SUCCEEDED(mStatus)) {
        if (NS_FAILED(rv))
            mStatus = rv;
        else if (avail) {
            // if stream is now closed, advance to STATE_STOP right away.
            // Available may return 0 bytes available at the moment; that
            // would not mean that we are done.
            // XXX async streams should have a GetStatus method!
            rv = mAsyncStream->Available(&avail);
            if (NS_SUCCEEDED(rv))
                return STATE_TRANSFER;
        }
    }
    return STATE_STOP;
}

Here is the call graph for this function:

void nsIRequest::resume ( ) [inherited]

Resumes the current request.

This may have the effect of re-opening any underlying transport and will resume the delivery of data to any open streams.

void nsIRequest::suspend ( ) [inherited]

Suspends the current request.

This may have the effect of closing any underlying transport (in order to free up resources), although any open streams remain logically opened and will continue delivering data when the transport is resumed.

NOTE: some implementations are unable to immediately suspend, and may continue to deliver events already posted to an event queue. In general, callers should be capable of handling events even after suspending a request.


Member Data Documentation

Definition at line 72 of file nsInputStreamPump.h.

Definition at line 86 of file nsInputStreamPump.h.

const unsigned long nsIRequest::INHIBIT_CACHING = 1 << 7 [inherited]

This flag prevents caching of any kind.

It does not, however, prevent cached content from being used to satisfy this request.

Definition at line 153 of file nsIRequest.idl.

const unsigned long nsIRequest::INHIBIT_PERSISTENT_CACHING = 1 << 8 [inherited]

This flag prevents caching on disk (or other persistent media), which may be needed to preserve privacy.

For HTTPS, this flag is set auto- matically.

Definition at line 160 of file nsIRequest.idl.

const unsigned long nsIRequest::LOAD_BACKGROUND = 1 << 0 [inherited]

Don't deliver status notifications to the nsIProgressEventSink, or keep this load from completing the nsILoadGroup it may belong to.

Definition at line 143 of file nsIRequest.idl.

const unsigned long nsIRequest::LOAD_BYPASS_CACHE = 1 << 9 [inherited]

Force an end-to-end download of content data from the origin server.

This flag is used for a shift-reload.

Definition at line 172 of file nsIRequest.idl.

const unsigned long nsIRequest::LOAD_FROM_CACHE = 1 << 10 [inherited]

Load from the cache, bypassing protocol specific validation logic.

This flag is used when browsing via history. It is not recommended for normal browsing as it may likely violate reasonable assumptions made by the server and confuse users.

Definition at line 180 of file nsIRequest.idl.

const unsigned long nsIRequest::LOAD_NORMAL = 0 [inherited]

No special load flags:

Definition at line 137 of file nsIRequest.idl.

The load flags of this request.

Bits 0-15 are reserved.

When added to a load group, this request's load flags are merged with the load flags of the load group.

Definition at line 128 of file nsIRequest.idl.

The load group of this request.

While pending, the request is a member of the load group. It is the responsibility of the request to implement this policy.

Definition at line 120 of file nsIRequest.idl.

Definition at line 108 of file nsInputStreamPump.h.

Definition at line 118 of file nsInputStreamPump.h.

Definition at line 106 of file nsInputStreamPump.h.

Definition at line 116 of file nsInputStreamPump.h.

Definition at line 104 of file nsInputStreamPump.h.

Definition at line 105 of file nsInputStreamPump.h.

Definition at line 115 of file nsInputStreamPump.h.

Definition at line 103 of file nsInputStreamPump.h.

Definition at line 112 of file nsInputStreamPump.h.

Definition at line 111 of file nsInputStreamPump.h.

Definition at line 102 of file nsInputStreamPump.h.

Definition at line 113 of file nsInputStreamPump.h.

Definition at line 107 of file nsInputStreamPump.h.

Definition at line 110 of file nsInputStreamPump.h.

Definition at line 109 of file nsInputStreamPump.h.

Definition at line 114 of file nsInputStreamPump.h.

Definition at line 117 of file nsInputStreamPump.h.

readonly attribute AUTF8String nsIRequest::name [inherited]

The name of the request.

Often this is the URI of the request.

Definition at line 55 of file nsIRequest.idl.

Definition at line 71 of file nsInputStreamPump.h.

Definition at line 70 of file nsInputStreamPump.h.

readonly attribute nsresult nsIRequest::status [inherited]

The error status associated with the request.

Definition at line 77 of file nsIRequest.idl.

Definition at line 67 of file nsInputStreamPump.h.

Definition at line 69 of file nsInputStreamPump.h.

Definition at line 68 of file nsInputStreamPump.h.

const unsigned long nsIRequest::VALIDATE_ALWAYS = 1 << 11 [inherited]

The following flags control the frequency of cached content validation when neither LOAD_BYPASS_CACHE or LOAD_FROM_CACHE are set.

By default, cached content is automatically validated if necessary before reuse.

VALIDATE_ALWAYS forces validation of any cached content independent of its expiration time.

VALIDATE_NEVER disables validation of expired content.

VALIDATE_ONCE_PER_SESSION disables validation of expired content, provided it has already been validated (at least once) since the start of this session.

NOTE TO IMPLEMENTORS: These flags are intended for normal browsing, and they should therefore not apply to content that must be validated before each use. Consider, for example, a HTTP response with a "Cache-control: no-cache" header. According to RFC2616, this response must be validated before it can be taken from a cache. Breaking this requirement could result in incorrect and potentially undesirable side-effects.

Definition at line 204 of file nsIRequest.idl.

const unsigned long nsIRequest::VALIDATE_NEVER = 1 << 12 [inherited]

Definition at line 205 of file nsIRequest.idl.

const unsigned long nsIRequest::VALIDATE_ONCE_PER_SESSION = 1 << 13 [inherited]

Definition at line 206 of file nsIRequest.idl.


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