Bug 217433. Implement nsIRequest::Suspend and ::Resume for the data: channel, by using nsIInputStreamPump.

r=darin sr=bzbarsky
This commit is contained in:
cbiesinger%web.de 2003-10-10 13:41:20 +00:00
Родитель e49b147dce
Коммит b78a596326
2 изменённых файлов: 65 добавлений и 111 удалений

Просмотреть файл

@ -52,14 +52,10 @@
#include "nsNetSegmentUtils.h"
#include "nsCRT.h"
#include "nsEscape.h"
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
#include "nsNetCID.h"
// nsDataChannel methods
nsDataChannel::nsDataChannel() :
mStatus(NS_OK),
mLoadFlags(nsIRequest::LOAD_NORMAL),
mContentLength(-1),
mOpened(PR_FALSE)
{
@ -78,11 +74,14 @@ NS_IMPL_ISUPPORTS5(nsDataChannel,
nsresult
nsDataChannel::Init(nsIURI* uri)
{
nsresult rv;
// Data urls contain all the data within the url string itself.
mUrl = uri;
nsresult rv;
mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
rv = ParseData();
return rv;
@ -249,17 +248,13 @@ nsDataChannel::GetName(nsACString &result)
NS_IMETHODIMP
nsDataChannel::IsPending(PRBool *result)
{
// This request is pending if there is an active stream listener...
*result = (mListener) ? PR_TRUE : PR_FALSE;
return NS_OK;
return mPump->IsPending(result);
}
NS_IMETHODIMP
nsDataChannel::GetStatus(nsresult *status)
{
*status = mStatus;
return NS_OK;
return mPump->GetStatus(status);
}
NS_IMETHODIMP
@ -267,22 +262,46 @@ nsDataChannel::Cancel(nsresult status)
{
NS_ASSERTION(NS_FAILED(status), "shouldn't cancel with a success code");
mStatus = status;
return NS_OK;
return mPump->Cancel(status);
}
NS_IMETHODIMP
nsDataChannel::Suspend(void)
{
// This channel is not suspendable...
return NS_ERROR_FAILURE;
return mPump->Suspend();
}
NS_IMETHODIMP
nsDataChannel::Resume(void)
{
// This channel is not resumable...
return NS_ERROR_FAILURE;
return mPump->Resume();
}
NS_IMETHODIMP
nsDataChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsDataChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsDataChannel::GetLoadFlags(PRUint32 *aLoadFlags)
{
return mPump->GetLoadFlags(aLoadFlags);
}
NS_IMETHODIMP
nsDataChannel::SetLoadFlags(PRUint32 aLoadFlags)
{
return mPump->SetLoadFlags(aLoadFlags);
}
////////////////////////////////////////////////////////////////////////////////
@ -325,63 +344,23 @@ nsDataChannel::Open(nsIInputStream **_retval)
NS_IMETHODIMP
nsDataChannel::AsyncOpen(nsIStreamListener *aListener, nsISupports *ctxt)
{
nsresult rv;
nsCOMPtr<nsIEventQueue> eventQ;
nsCOMPtr<nsIStreamListener> listener;
nsCOMPtr<nsIEventQueueService> eventQService =
do_GetService(kEventQueueServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ));
if (NS_FAILED(rv)) return rv;
// we'll just fire everything off at once because we've already got all
// the data.
rv = NS_NewAsyncStreamListener(getter_AddRefs(listener), this, eventQ);
if (NS_FAILED(rv)) return rv;
// Hold onto the real consumer...
mListener = aListener;
mOpened = PR_TRUE;
// Add the request to the loadgroup (if available)
if (mLoadGroup) {
mLoadGroup->AddRequest(this, nsnull);
}
nsresult rv = mPump->Init(mDataStream, -1, -1, 0, 0, PR_FALSE);
if (NS_FAILED(rv))
return rv;
// Add to load group
if (mLoadGroup)
mLoadGroup->AddRequest(this, nsnull);
// Start the read
return mPump->AsyncRead(this, ctxt);
// Next, queue up asynchronous stream notifications for OnStartRequest,
// a single OnDataAvailable (containing all of the data) and an
// OnStopRequest...
//
// These notifications will be processed when control returns to the
// message pump and the PLEvents are processed...
//
mStatus = listener->OnStartRequest(this, ctxt);
// Only fire OnDataAvailable(...) if OnStartRequest(...) succeeded!
if (NS_SUCCEEDED(mStatus)) {
mStatus = listener->OnDataAvailable(this, ctxt, mDataStream,
0, mContentLength);
}
// Always fire OnStopRequest(...) even if an error occurred!
(void) listener->OnStopRequest(this, ctxt, mStatus);
return NS_OK;
}
NS_IMETHODIMP
nsDataChannel::GetLoadFlags(PRUint32 *aLoadFlags)
{
*aLoadFlags = mLoadFlags;
return NS_OK;
}
NS_IMETHODIMP
nsDataChannel::SetLoadFlags(PRUint32 aLoadFlags)
{
mLoadFlags = aLoadFlags;
return NS_OK;
}
NS_IMETHODIMP
@ -433,21 +412,6 @@ nsDataChannel::SetContentLength(PRInt32 aContentLength)
return NS_OK;
}
NS_IMETHODIMP
nsDataChannel::GetLoadGroup(nsILoadGroup* *aLoadGroup)
{
*aLoadGroup = mLoadGroup;
NS_IF_ADDREF(*aLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsDataChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
{
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsDataChannel::GetOwner(nsISupports* *aOwner)
{
@ -493,35 +457,26 @@ nsDataChannel::GetSecurityInfo(nsISupports **sec)
NS_IMETHODIMP
nsDataChannel::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
{
if (NS_SUCCEEDED(mStatus)) {
mStatus = mListener->OnStartRequest(request, ctxt);
if (mListener) {
return mListener->OnStartRequest(this, ctxt);
}
return mStatus;
return NS_OK;
}
NS_IMETHODIMP
nsDataChannel::OnStopRequest(nsIRequest *request, nsISupports *ctxt,
nsresult status)
{
// If the request has already failed for some reason, then pass out that
// failure code...
//
if (NS_SUCCEEDED(mStatus)) {
mStatus = status;
}
if (mListener) {
(void) mListener->OnStopRequest(request, ctxt, mStatus);
mListener->OnStopRequest(this, ctxt, status);
// Drop the reference to the stream listener -- it is no longer needed.
mListener = nsnull;
}
// Drop the reference to the stream listener -- it is no longer needed.
mListener = nsnull;
// Remove this request from the load group -- it is complete.
if (mLoadGroup) {
mLoadGroup->RemoveRequest(this, nsnull, mStatus);
}
// Remove from Loadgroup
if (mLoadGroup)
mLoadGroup->RemoveRequest(this, nsnull, status);
return NS_OK;
}
@ -535,11 +490,10 @@ nsDataChannel::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
nsIInputStream *input,
PRUint32 offset, PRUint32 count)
{
if (NS_SUCCEEDED(mStatus)) {
mStatus = mListener->OnDataAvailable(request, ctxt, input,
offset, count);
if (mListener) {
return mListener->OnDataAvailable(this, ctxt, input,
offset, count);
}
return mStatus;
return NS_OK;
}

Просмотреть файл

@ -49,6 +49,7 @@
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsCOMPtr.h"
#include "nsIInputStreamPump.h"
class nsDataChannel : public nsIDataChannel,
public nsIStreamListener {
@ -76,15 +77,14 @@ protected:
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mUrl;
nsCOMPtr<nsIInputStream> mDataStream;
nsresult mStatus;
PRUint32 mLoadFlags;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCString mContentType;
nsCString mContentCharset;
PRInt32 mContentLength;
nsCOMPtr<nsISupports> mOwner;
nsCOMPtr<nsIStreamListener> mListener;
PRBool mOpened;
nsCOMPtr<nsIStreamListener> mListener;
nsCOMPtr<nsIInputStreamPump> mPump;
};
#endif /* nsDataChannel_h___ */