зеркало из https://github.com/mozilla/pjs.git
Bug 62566. nsIChannel::AsyncWrite interface revision and related cleanup.
r=dougt@netcape.com, sr=mscott@netscape.com.
This commit is contained in:
Родитель
ef7f12f026
Коммит
6bfaf3912c
|
@ -557,6 +557,7 @@ sub BuildClientDist()
|
|||
InstallFromManifest(":mozilla:uriloader:exthandler:MANIFEST_IDL", "$distdirectory:idl:");
|
||||
|
||||
#NETWERK
|
||||
InstallFromManifest(":mozilla:netwerk:build:MANIFEST", "$distdirectory:netwerk:");
|
||||
InstallFromManifest(":mozilla:netwerk:base:public:MANIFEST", "$distdirectory:netwerk:");
|
||||
InstallFromManifest(":mozilla:netwerk:base:public:MANIFEST_IDL", "$distdirectory:idl:");
|
||||
InstallFromManifest(":mozilla:netwerk:socket:base:MANIFEST_IDL", "$distdirectory:idl:");
|
||||
|
|
|
@ -271,7 +271,7 @@ nsCachedChromeChannel::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCachedChromeChannel::AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt)
|
||||
nsCachedChromeChannel::AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("don't do that");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -349,7 +349,7 @@ public:
|
|||
NS_IMETHOD OpenOutputStream(nsIOutputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
||||
NS_IMETHOD AsyncOpen(nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncRead(nsIStreamListener *listener, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD GetLoadAttributes(nsLoadFlags *aLoadAttributes) { *aLoadAttributes = nsIChannel::LOAD_NORMAL; return NS_OK; }
|
||||
NS_IMETHOD SetLoadAttributes(nsLoadFlags aLoadAttributes) { return NS_OK; }
|
||||
NS_IMETHOD GetContentType(char * *aContentType) { *aContentType = nsnull; return NS_OK; }
|
||||
|
|
|
@ -219,7 +219,7 @@ NS_IMETHODIMP nsWebBrowserPersist::SaveURI(nsIURI *aURI, nsIInputStream *aPostDa
|
|||
mInputStream = inStream;
|
||||
|
||||
// Get the output channel ready for writing
|
||||
rv = outputChannel->AsyncWrite(inStream, NS_STATIC_CAST(nsIStreamObserver *, this), nsnull);
|
||||
rv = NS_AsyncWriteFromStream(outputChannel, inStream, NS_STATIC_CAST(nsIStreamObserver *, this), nsnull);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
OnEndDownload();
|
||||
|
|
|
@ -202,8 +202,7 @@ nsDateTimeChannel::AsyncRead(nsIStreamListener *aListener,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsDateTimeChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("nsDateTimeChannel::AsyncWrite");
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "nsMimeTypes.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsITXTToHTMLConv.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
||||
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||
|
@ -250,8 +251,7 @@ nsFingerChannel::AsyncRead(nsIStreamListener *aListener, nsISupports *ctxt)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsFingerChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("nsFingerChannel::AsyncWrite");
|
||||
|
@ -540,7 +540,7 @@ nsFingerChannel::SendRequest(nsIChannel* aChannel) {
|
|||
|
||||
rv = aChannel->SetTransferCount(requestBuffer.Length());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = aChannel->AsyncWrite(charstream, this, 0);
|
||||
rv = NS_AsyncWriteFromStream(aChannel, charstream, this, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,8 +316,8 @@ NS_IMETHODIMP nsDOMParserChannel::AsyncRead(nsIStreamListener *listener, nsISupp
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void asyncWrite (in nsIInputStream fromStream, in nsIStreamObserver observer, in nsISupports ctxt); */
|
||||
NS_IMETHODIMP nsDOMParserChannel::AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt)
|
||||
/* void asyncWrite (in nsIStreamProvider provider, in nsISupports ctxt); */
|
||||
NS_IMETHODIMP nsDOMParserChannel::AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -656,9 +656,8 @@ public:
|
|||
NS_IMETHOD SetURI(nsIURI* aURI) { gURI = aURI; NS_ADDREF(gURI); return NS_OK; }
|
||||
NS_IMETHOD OpenInputStream(nsIInputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
||||
NS_IMETHOD OpenOutputStream(nsIOutputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
||||
NS_IMETHOD AsyncOpen(nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncRead(nsIStreamListener *listener, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD GetLoadAttributes(nsLoadFlags *aLoadAttributes) { *aLoadAttributes = nsIChannel::LOAD_NORMAL; return NS_OK; }
|
||||
NS_IMETHOD SetLoadAttributes(nsLoadFlags aLoadAttributes) { return NS_OK; }
|
||||
NS_IMETHOD GetContentType(char * *aContentType) { *aContentType = nsnull; return NS_OK; }
|
||||
|
|
|
@ -656,9 +656,8 @@ public:
|
|||
NS_IMETHOD SetURI(nsIURI* aURI) { gURI = aURI; NS_ADDREF(gURI); return NS_OK; }
|
||||
NS_IMETHOD OpenInputStream(nsIInputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
||||
NS_IMETHOD OpenOutputStream(nsIOutputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
||||
NS_IMETHOD AsyncOpen(nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncRead(nsIStreamListener *listener, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD GetLoadAttributes(nsLoadFlags *aLoadAttributes) { *aLoadAttributes = nsIChannel::LOAD_NORMAL; return NS_OK; }
|
||||
NS_IMETHOD SetLoadAttributes(nsLoadFlags aLoadAttributes) { return NS_OK; }
|
||||
NS_IMETHOD GetContentType(char * *aContentType) { *aContentType = nsnull; return NS_OK; }
|
||||
|
|
|
@ -416,7 +416,7 @@ NS_IMETHODIMP nsMsgProtocol::AsyncRead(nsIStreamListener *listener, nsISupports
|
|||
return LoadUrl(m_url, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgProtocol::AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt)
|
||||
NS_IMETHODIMP nsMsgProtocol::AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("AsyncWrite");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
|
|
@ -341,7 +341,7 @@ NS_IMETHODIMP nsMailtoChannel::AsyncRead(nsIStreamListener *listener, nsISupport
|
|||
return listener->OnStartRequest(this, ctxt);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailtoChannel::AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt)
|
||||
NS_IMETHODIMP nsMailtoChannel::AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("AsyncWrite");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
|
|
@ -7008,7 +7008,7 @@ NS_IMETHODIMP nsImapMockChannel::AsyncRead(nsIStreamListener *listener, nsISuppo
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMockChannel::AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt)
|
||||
NS_IMETHODIMP nsImapMockChannel::AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("nsImapMockChannel::AsyncWrite");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
|
|
@ -392,8 +392,7 @@ nsJARChannel::AsyncReadJARElement()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::AsyncWrite(nsIInputStream* fromStream,
|
||||
nsIStreamObserver* observer,
|
||||
nsJARChannel::AsyncWrite(nsIStreamProvider* provider,
|
||||
nsISupports* ctxt)
|
||||
{
|
||||
NS_NOTREACHED("nsJARChannel::AsyncWrite");
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
* nsISupports implementation
|
||||
*--------------------------------------------*/
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsJARInputStream, nsIInputStream);
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsJARInputStream, nsIInputStream);
|
||||
|
||||
/*----------------------------------------------------------
|
||||
* nsJARInputStream implementation
|
||||
|
|
|
@ -19,6 +19,7 @@ nsIStreamListener.idl
|
|||
nsIStreamLoader.idl
|
||||
nsIDownloader.idl
|
||||
nsIStreamObserver.idl
|
||||
nsIStreamProvider.idl
|
||||
nsIURI.idl
|
||||
nsIURL.idl
|
||||
nsIURLParser.idl
|
||||
|
|
|
@ -51,10 +51,11 @@ XPIDLSRCS = \
|
|||
nsISocketTransport.idl \
|
||||
nsISocketTransportService.idl \
|
||||
nsIStreamIO.idl \
|
||||
nsIStreamObserver.idl \
|
||||
nsIStreamListener.idl \
|
||||
nsIStreamProvider.idl \
|
||||
nsIStreamLoader.idl \
|
||||
nsISocketTransport.idl \
|
||||
nsIStreamObserver.idl \
|
||||
nsIURI.idl \
|
||||
nsIURL.idl \
|
||||
nsIURLParser.idl \
|
||||
|
|
|
@ -54,6 +54,7 @@ XPIDLSRCS = \
|
|||
.\nsISocketTransportService.idl \
|
||||
.\nsIStreamIO.idl \
|
||||
.\nsIStreamListener.idl \
|
||||
.\nsIStreamProvider.idl \
|
||||
.\nsIStreamLoader.idl \
|
||||
.\nsIDownloader.idl \
|
||||
.\nsIStreamObserver.idl \
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
|
@ -27,6 +27,7 @@ interface nsIInputStream;
|
|||
interface nsIOutputStream;
|
||||
interface nsIStreamObserver;
|
||||
interface nsIStreamListener;
|
||||
interface nsIStreamProvider;
|
||||
interface nsILoadGroup;
|
||||
interface nsIInterfaceRequestor;
|
||||
interface nsIFile;
|
||||
|
@ -43,7 +44,7 @@ typedef unsigned long nsLoadFlags;
|
|||
* request can be issued in one of several ways:
|
||||
*
|
||||
* - AsyncRead and AsyncWrite allow for asynchronous requests, calling
|
||||
* back the user's stream listener or observer,
|
||||
* back the user's stream listener or provider,
|
||||
* - OpenInputStream and OpenOutputStream allow for synchronous reads
|
||||
* and writes on the underlying channel.
|
||||
*
|
||||
|
@ -187,7 +188,7 @@ interface nsIChannel : nsIRequest
|
|||
readonly attribute nsIFile localFile;
|
||||
|
||||
/**
|
||||
* Setting pipeliningAllowed causes the load of a URL (issued via asyncOpen,
|
||||
* Setting pipeliningAllowed causes the load of a URL (issued via
|
||||
* asyncRead or asyncWrite) to be deferred in order to allow the request to
|
||||
* be pipelined for greater throughput efficiency. Pipelined requests will
|
||||
* be forced to load when the first non-pipelined request is issued.
|
||||
|
@ -209,13 +210,16 @@ interface nsIChannel : nsIRequest
|
|||
*/
|
||||
const unsigned long LOAD_NORMAL = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Don't deliver status notifications to the nsIProgressEventSink, or keep
|
||||
* this load from completing the nsILoadGroup it may belong to:
|
||||
*/
|
||||
const unsigned long LOAD_BACKGROUND = 1 << 0;
|
||||
|
||||
/**
|
||||
* Used exclusively by the uriloader and docshell to indicate whether or
|
||||
* not this channel corresponds to the toplevel document.
|
||||
*/
|
||||
const unsigned long LOAD_DOCUMENT_URI = 1 << 1;
|
||||
|
||||
/**
|
||||
|
@ -288,45 +292,35 @@ interface nsIChannel : nsIRequest
|
|||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Opens a blocking input stream to the URL's specified source.
|
||||
* @param startPosition - The offset from the start of the data
|
||||
* from which to read.
|
||||
* @param readCount - The number of bytes to read. If -1, everything
|
||||
* up to the end of the data is read. If greater than the end of
|
||||
* the data, the amount available is returned in the stream.
|
||||
* Opens a blocking input stream to the URI's specified source. This
|
||||
* call may block until the input stream is available.
|
||||
*/
|
||||
nsIInputStream openInputStream();
|
||||
|
||||
/**
|
||||
* Opens a blocking output stream to the URL's specified destination.
|
||||
* @param startPosition - The offset from the start of the data
|
||||
* from which to begin writing.
|
||||
* Opens a blocking output stream to the URI's specified destination. This
|
||||
* call may block until the output stream is available.
|
||||
*/
|
||||
nsIOutputStream openOutputStream();
|
||||
|
||||
/**
|
||||
* Reads asynchronously from the URL's specified source. Notifications
|
||||
* are provided to the stream listener on the thread of the specified
|
||||
* event queue.
|
||||
* The startPosition argument designates the offset in the source where
|
||||
* the data will be read.
|
||||
* If the readCount == -1 then all the available data is delivered to
|
||||
* the stream listener.
|
||||
* Reads asynchronously from the URI's specified source. Notifications
|
||||
* are provided to the stream listener on the calling thread.
|
||||
*
|
||||
* @param listener - notification handler.
|
||||
* @param ctxt - application context passed to methods invoked on listener.
|
||||
*/
|
||||
void asyncRead(in nsIStreamListener listener,
|
||||
in nsISupports ctxt);
|
||||
|
||||
/**
|
||||
* Writes asynchronously to the URL's specified destination. Notifications
|
||||
* are provided to the stream observer on the thread of the specified
|
||||
* event queue.
|
||||
* The startPosition argument designates the offset in the destination where
|
||||
* the data will be written.
|
||||
* If the writeCount == -1, then all the available data in the input
|
||||
* stream is written.
|
||||
* Writes asynchronously to the URI's specified destination. Notifications
|
||||
* are provided to the stream provider on the calling thread.
|
||||
*
|
||||
* @param provider - notification handler.
|
||||
* @param ctxt - application context passed to methods invoked on provider.
|
||||
*/
|
||||
void asyncWrite(in nsIInputStream fromStream,
|
||||
in nsIStreamObserver observer,
|
||||
void asyncWrite(in nsIStreamProvider provider,
|
||||
in nsISupports ctxt);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
|
@ -22,21 +22,85 @@
|
|||
|
||||
#include "nsIStreamObserver.idl"
|
||||
|
||||
interface nsIInputStream;
|
||||
interface nsIChannel;
|
||||
interface nsIInputStream;
|
||||
interface nsIOutputStream;
|
||||
interface nsIEventQueue;
|
||||
|
||||
/**
|
||||
* The nsIChannel::AsyncRead notification handler. It accepts
|
||||
* data from the channel, when the channel is ready to provide it.
|
||||
*/
|
||||
[scriptable, uuid(1a637020-1482-11d3-9333-00104ba0fd40)]
|
||||
interface nsIStreamListener : nsIStreamObserver
|
||||
{
|
||||
/**
|
||||
* Called when there is data to be read from the channel.
|
||||
*
|
||||
* @param channel - the channel being read
|
||||
* @param ctxt - opaque parameter passed to AsyncRead
|
||||
* @param input - temporary input stream for reading data chunk
|
||||
* @param offset - current stream position (informational)
|
||||
* @param count - number of bytes that can be read without blocking
|
||||
*
|
||||
* @return NS_OK - if successfully read something.
|
||||
* @return NS_BASE_STREAM_CLOSED - if done reading data. NOTE: this is
|
||||
* NOT equivalent to reading zero bytes and returning NS_OK.
|
||||
* @return NS_BASE_STREAM_WOULD_BLOCK - if no data can be read at
|
||||
* this time. This implicitly calls Suspend on the channel. Call
|
||||
* Resume on the channel to continue the AsyncRead when more data
|
||||
* becomes available.
|
||||
* @return <other-error> - if failure.
|
||||
*/
|
||||
void onDataAvailable(in nsIChannel channel,
|
||||
in nsISupports ctxt,
|
||||
in nsIInputStream inStr,
|
||||
in unsigned long sourceOffset,
|
||||
in nsIInputStream input,
|
||||
in unsigned long offset,
|
||||
in unsigned long count);
|
||||
};
|
||||
|
||||
/**
|
||||
* A stream listener proxy is used to ship data over to another thread specified
|
||||
* by the thread's event queue. The "true" stream listener's methods are
|
||||
* invoked on the other thread.
|
||||
*
|
||||
* This interface only provides the initialization needed after construction.
|
||||
* Otherwise, these objects may be used as a nsIStreamListener.
|
||||
*/
|
||||
[scriptable, uuid(e400e688-6b54-4a84-8c4e-56b40281981a)]
|
||||
interface nsIStreamListenerProxy : nsIStreamListener
|
||||
{
|
||||
/**
|
||||
* Initializes an nsIStreamListenerProxy.
|
||||
*
|
||||
* @param listener - receives listener notifications on the other thread
|
||||
* @param eventQ - may be NULL indicating the calling thread's event queue
|
||||
* @param bufferSegmentSize - passing zero indicates the default
|
||||
* @param bufferMaxSize - passing zero indicates the default
|
||||
*/
|
||||
void init(in nsIStreamListener listener,
|
||||
in nsIEventQueue eventQ,
|
||||
in unsigned long bufferSegmentSize,
|
||||
in unsigned long bufferMaxSize);
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple stream listener can be used with AsyncRead to supply data to
|
||||
* a output stream.
|
||||
*/
|
||||
[scriptable, uuid(a9b84f6a-0824-4278-bae6-bfca0570a26e)]
|
||||
interface nsISimpleStreamListener : nsIStreamListener
|
||||
{
|
||||
/**
|
||||
* Initialize the simple stream listener.
|
||||
*
|
||||
* @param sink - data will be read from the channel to this output stream
|
||||
* @param observer - optional stream observer (can be NULL)
|
||||
*/
|
||||
void init(in nsIOutputStream sink,
|
||||
in nsIStreamObserver observer);
|
||||
};
|
||||
|
||||
/**
|
||||
* An asynchronous stream listener is used to ship data over to another thread specified
|
||||
* by the thread's event queue. The receiver stream listener is then used to receive
|
||||
|
@ -55,42 +119,3 @@ interface nsIAsyncStreamListener : nsIStreamListener
|
|||
void init(in nsIStreamListener receiver,
|
||||
in nsIEventQueue eventQueue);
|
||||
};
|
||||
|
||||
/**
|
||||
* A synchronous stream listener pushes data through a pipe that ends up
|
||||
* in an input stream to be read by another thread.
|
||||
*
|
||||
* This interface only provides the initialization needed after construction. Otherwise,
|
||||
* these objects are used simply as nsIStreamListener.
|
||||
*/
|
||||
[scriptable, uuid(1f9fb93e-91bf-11d3-8cd9-0060b0fc14a3)]
|
||||
interface nsISyncStreamListener : nsIStreamListener
|
||||
{
|
||||
/**
|
||||
* Initializes an nsISyncStreamListener.
|
||||
*/
|
||||
void init(out nsIInputStream inStream,
|
||||
out nsIOutputStream outStream);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
// Use this CID to construct an nsIAsyncStreamListener
|
||||
#define NS_ASYNCSTREAMLISTENER_CID \
|
||||
{ /* 60047bb2-91c0-11d3-8cd9-0060b0fc14a3 */ \
|
||||
0x60047bb2, \
|
||||
0x91c0, \
|
||||
0x11d3, \
|
||||
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
|
||||
}
|
||||
|
||||
// Use this CID to construct an nsISyncStreamListener
|
||||
#define NS_SYNCSTREAMLISTENER_CID \
|
||||
{ /* 65fa5cb2-91c0-11d3-8cd9-0060b0fc14a3 */ \
|
||||
0x65fa5cb2, \
|
||||
0x91c0, \
|
||||
0x11d3, \
|
||||
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
|
||||
}
|
||||
|
||||
%}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
|
@ -22,27 +22,55 @@
|
|||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIEventQueue;
|
||||
interface nsIChannel;
|
||||
interface nsIEventQueue;
|
||||
|
||||
[scriptable, uuid(fd91e2e0-1481-11d3-9333-00104ba0fd40)]
|
||||
interface nsIStreamObserver : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called to signify the beginning of an asyncronous request.
|
||||
* Called to signify the beginning of an asynchronous request.
|
||||
*
|
||||
* @param channel - channel being observed
|
||||
* @param ctxt - user specified data passed to AsyncRead/Write
|
||||
*/
|
||||
void onStartRequest(in nsIChannel channel,
|
||||
in nsISupports ctxt);
|
||||
|
||||
/**
|
||||
* Called to signify the end of an asyncronous request.
|
||||
* @param notif - a notification object containing any error code and error parameters
|
||||
* (may be null if the notification status is NS_OK)
|
||||
* Called to signify the end of an asynchronous request. This
|
||||
* call is always preceded by a call to onStartRequest.
|
||||
*
|
||||
* @param channel - channel being observed
|
||||
* @param ctxt - user specified data passed to AsyncRead/Write
|
||||
* @param statusCode - reason for stopping (NS_OK if completed successfully)
|
||||
* @param statusText - human readable reason for stopping (can be NULL)
|
||||
*/
|
||||
void onStopRequest(in nsIChannel channel,
|
||||
in nsISupports ctxt,
|
||||
in nsresult status,
|
||||
in wstring statusArg);
|
||||
in nsresult statusCode,
|
||||
in wstring statusText);
|
||||
};
|
||||
|
||||
/**
|
||||
* A stream observer proxy is used to ship data over to another thread specified
|
||||
* by the thread's event queue. The "true" stream observer's methods are
|
||||
* invoked on the other thread.
|
||||
*
|
||||
* This interface only provides the initialization needed after construction. Otherwise,
|
||||
* these objects are used simply as nsIStreamObserver's.
|
||||
*/
|
||||
[scriptable, uuid(3c9b532e-db84-4ecf-aa6a-4d38a9c4c5f0)]
|
||||
interface nsIStreamObserverProxy : nsIStreamObserver
|
||||
{
|
||||
/**
|
||||
* Initializes an nsIStreamObserverProxy.
|
||||
*
|
||||
* @param observer - receives observer notifications on the other thread
|
||||
* @param eventQ - may be NULL indicating the calling thread's event queue
|
||||
*/
|
||||
void init(in nsIStreamObserver observer,
|
||||
in nsIEventQueue eventQ);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -65,22 +93,8 @@ interface nsIAsyncStreamObserver : nsIStreamObserver
|
|||
};
|
||||
|
||||
%{C++
|
||||
|
||||
// Use this CID to construct an nsIAsyncStreamObserver
|
||||
#define NS_ASYNCSTREAMOBSERVER_CID \
|
||||
{ /* fcc7c380-91b3-11d3-8cd9-0060b0fc14a3 */ \
|
||||
0xfcc7c380, \
|
||||
0x91b3, \
|
||||
0x11d3, \
|
||||
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Generic status codes for OnStopRequest:
|
||||
|
||||
#define NS_BINDING_SUCCEEDED NS_OK
|
||||
#define NS_BINDING_FAILED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 1)
|
||||
#define NS_BINDING_ABORTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 2)
|
||||
|
||||
#define NS_BINDING_SUCCEEDED NS_OK
|
||||
#define NS_BINDING_FAILED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 1)
|
||||
#define NS_BINDING_ABORTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 2)
|
||||
%}
|
||||
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsIStreamObserver.idl"
|
||||
|
||||
interface nsIChannel;
|
||||
interface nsIInputStream;
|
||||
interface nsIOutputStream;
|
||||
interface nsIEventQueue;
|
||||
|
||||
/**
|
||||
* The nsIChannel::AsyncWrite notification handler. It provides
|
||||
* data to the channel, when the channel is ready to accept it.
|
||||
*/
|
||||
[scriptable, uuid(d10ef7a9-b728-43d4-9c49-74172186d691)]
|
||||
interface nsIStreamProvider : nsIStreamObserver
|
||||
{
|
||||
/**
|
||||
* Called when data may be written to the channel.
|
||||
*
|
||||
* @param channel - the channel being written to
|
||||
* @param ctxt - opaque parameter passed to AsyncWrite
|
||||
* @param output - output stream for writing data chunk
|
||||
* @param offset - current stream position (informational)
|
||||
* @param count - number of bytes that can be written without blocking
|
||||
*
|
||||
* @return NS_OK - if successfully wrote something.
|
||||
* @return NS_BASE_STREAM_CLOSED - if done writing data. NOTE: this is
|
||||
* NOT equivalent to writing zero bytes and returning NS_OK.
|
||||
* @return NS_BASE_STREAM_WOULD_BLOCK - if no data can be written at
|
||||
* this time. This implicitly calls Suspend on the channel. Call
|
||||
* Resume on the channel to continue the AsyncWrite when more data
|
||||
* becomes available.
|
||||
* @return <other-error> - if failure.
|
||||
*/
|
||||
void onDataWritable(in nsIChannel channel,
|
||||
in nsISupports ctxt,
|
||||
in nsIOutputStream output,
|
||||
in unsigned long offset,
|
||||
in unsigned long count);
|
||||
};
|
||||
|
||||
/**
|
||||
* A stream provider proxy is used to ship data over to another thread specified
|
||||
* by the thread's event queue. The "true" stream provider's methods are
|
||||
* invoked on the other thread.
|
||||
*
|
||||
* This interface only provides the initialization needed after construction.
|
||||
* Otherwise, these objects may be used as a nsIStreamProvider.
|
||||
*/
|
||||
[scriptable, uuid(5c3b0bac-605a-49ac-880e-5c8b993f7d2b)]
|
||||
interface nsIStreamProviderProxy : nsIStreamProvider
|
||||
{
|
||||
/**
|
||||
* Initializes an nsIStreamProviderProxy.
|
||||
*
|
||||
* @param provider - receives provider notifications on the other thread.
|
||||
* @param eventQ - may be NULL indicating the calling thread's event queue.
|
||||
*/
|
||||
void init(in nsIStreamProvider provider,
|
||||
in nsIEventQueue eventQ,
|
||||
in unsigned long bufferSegmentSize,
|
||||
in unsigned long bufferMaxSize);
|
||||
};
|
||||
|
||||
/**
|
||||
* A simple stream provider can be used with AsyncWrite to supply data from
|
||||
* an existing input stream.
|
||||
*/
|
||||
[scriptable, uuid(c20bb3b9-0755-4eff-9222-3537f9e89082)]
|
||||
interface nsISimpleStreamProvider : nsIStreamProvider
|
||||
{
|
||||
/**
|
||||
* Initialize the simple stream provider.
|
||||
*
|
||||
* @param - data will be read from this input stream to the channel
|
||||
* @param - optional stream observer (can be NULL)
|
||||
*/
|
||||
void init(in nsIInputStream source,
|
||||
in nsIStreamObserver observer);
|
||||
};
|
|
@ -26,7 +26,9 @@
|
|||
#include "nsIURI.h"
|
||||
#include "netCore.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsString.h"
|
||||
|
@ -40,9 +42,12 @@
|
|||
#include "nsIDownloader.h"
|
||||
#include "nsIStreamLoader.h"
|
||||
#include "nsIStreamIO.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "prio.h" // for read/write flags, permissions, etc.
|
||||
|
||||
#include "nsNetCID.h"
|
||||
|
||||
// Helper, to simplify getting the I/O service.
|
||||
inline const nsGetServiceByCID
|
||||
do_GetIOService(nsresult* error = 0)
|
||||
|
@ -368,6 +373,139 @@ NS_NewStreamLoader(nsIStreamLoader* *result,
|
|||
return rv;
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
NS_NewStreamObserverProxy(nsIStreamObserver **aResult,
|
||||
nsIStreamObserver *aObserver,
|
||||
nsIEventQueue *aEventQ=nsnull)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStreamObserverProxy> proxy;
|
||||
static NS_DEFINE_CID(kStreamObserverProxyCID, NS_STREAMOBSERVERPROXY_CID);
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kStreamObserverProxyCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIStreamObserverProxy),
|
||||
getter_AddRefs(proxy));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = proxy->Init(aObserver, aEventQ);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*aResult = proxy;
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
NS_NewStreamListenerProxy(nsIStreamListener **aResult,
|
||||
nsIStreamListener *aListener,
|
||||
nsIEventQueue *aEventQ=nsnull,
|
||||
PRUint32 aBufferSegmentSize=0,
|
||||
PRUint32 aBufferMaxSize=0)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStreamListenerProxy> proxy;
|
||||
static NS_DEFINE_CID(kStreamListenerProxyCID, NS_STREAMLISTENERPROXY_CID);
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kStreamListenerProxyCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIStreamListenerProxy),
|
||||
getter_AddRefs(proxy));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = proxy->Init(aListener, aEventQ, aBufferSegmentSize, aBufferMaxSize);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*aResult = proxy;
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
NS_NewStreamProviderProxy(nsIStreamProvider **aResult,
|
||||
nsIStreamProvider *aProvider,
|
||||
nsIEventQueue *aEventQ=nsnull,
|
||||
PRUint32 aBufferSegmentSize=0,
|
||||
PRUint32 aBufferMaxSize=0)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStreamProviderProxy> proxy;
|
||||
static NS_DEFINE_CID(kStreamProviderProxyCID, NS_STREAMPROVIDERPROXY_CID);
|
||||
|
||||
rv = nsComponentManager::CreateInstance(kStreamProviderProxyCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIStreamProviderProxy),
|
||||
getter_AddRefs(proxy));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = proxy->Init(aProvider, aEventQ, aBufferSegmentSize, aBufferMaxSize);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*aResult = proxy;
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
NS_NewSimpleStreamListener(nsIStreamListener **aResult,
|
||||
nsIOutputStream *aSink,
|
||||
nsIStreamObserver *aObserver=nsnull)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISimpleStreamListener> listener;
|
||||
static NS_DEFINE_CID(kSimpleStreamListenerCID, NS_SIMPLESTREAMLISTENER_CID);
|
||||
rv = nsComponentManager::CreateInstance(kSimpleStreamListenerCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISimpleStreamListener),
|
||||
getter_AddRefs(listener));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = listener->Init(aSink, aObserver);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*aResult = listener.get();
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
NS_NewSimpleStreamProvider(nsIStreamProvider **aResult,
|
||||
nsIInputStream *aSource,
|
||||
nsIStreamObserver *aObserver=nsnull)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISimpleStreamProvider> provider;
|
||||
static NS_DEFINE_CID(kSimpleStreamProviderCID, NS_SIMPLESTREAMPROVIDER_CID);
|
||||
rv = nsComponentManager::CreateInstance(kSimpleStreamProviderCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISimpleStreamProvider),
|
||||
getter_AddRefs(provider));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = provider->Init(aSource, aObserver);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*aResult = provider.get();
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Depracated, prefer NS_NewStreamObserverProxy
|
||||
inline nsresult
|
||||
NS_NewAsyncStreamObserver(nsIStreamObserver **result,
|
||||
nsIStreamObserver *receiver,
|
||||
|
@ -389,6 +527,7 @@ NS_NewAsyncStreamObserver(nsIStreamObserver **result,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Depracated, prefer NS_NewStreamListenerProxy
|
||||
inline nsresult
|
||||
NS_NewAsyncStreamListener(nsIStreamListener **result,
|
||||
nsIStreamListener *receiver,
|
||||
|
@ -410,25 +549,79 @@ NS_NewAsyncStreamListener(nsIStreamListener **result,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Depracated, prefer a true synchonous implementation
|
||||
inline nsresult
|
||||
NS_NewSyncStreamListener(nsIInputStream **inStream,
|
||||
nsIOutputStream **outStream,
|
||||
nsIStreamListener **listener)
|
||||
NS_NewSyncStreamListener(nsIInputStream **aInStream,
|
||||
nsIOutputStream **aOutStream,
|
||||
nsIStreamListener **aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISyncStreamListener> lsnr;
|
||||
static NS_DEFINE_CID(kSyncStreamListenerCID, NS_SYNCSTREAMLISTENER_CID);
|
||||
rv = nsComponentManager::CreateInstance(kSyncStreamListenerCID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsISyncStreamListener),
|
||||
getter_AddRefs(lsnr));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = lsnr->Init(inStream, outStream);
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aInStream);
|
||||
NS_ENSURE_ARG_POINTER(aOutStream);
|
||||
|
||||
nsCOMPtr<nsIInputStream> pipeIn;
|
||||
nsCOMPtr<nsIOutputStream> pipeOut;
|
||||
|
||||
rv = NS_NewPipe(getter_AddRefs(pipeIn),
|
||||
getter_AddRefs(pipeOut),
|
||||
4*1024, // NS_SYNC_STREAM_LISTENER_SEGMENT_SIZE
|
||||
32*1024); // NS_SYNC_STREAM_LISTENER_BUFFER_SIZE
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*listener = lsnr;
|
||||
NS_ADDREF(*listener);
|
||||
rv = NS_NewSimpleStreamListener(aResult, pipeOut);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
*aInStream = pipeIn;
|
||||
NS_ADDREF(*aInStream);
|
||||
*aOutStream = pipeOut;
|
||||
NS_ADDREF(*aOutStream);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Calls AsyncWrite on the specified channel, with a stream provider that
|
||||
// reads data from the specified input stream.
|
||||
//
|
||||
inline nsresult
|
||||
NS_AsyncWriteFromStream(nsIChannel *aChannel,
|
||||
nsIInputStream *aSource,
|
||||
nsIStreamObserver *aObserver=NULL,
|
||||
nsISupports *aContext=NULL)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChannel);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStreamProvider> provider;
|
||||
rv = NS_NewSimpleStreamProvider(getter_AddRefs(provider),
|
||||
aSource,
|
||||
aObserver);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return aChannel->AsyncWrite(provider, aContext);
|
||||
}
|
||||
|
||||
//
|
||||
// Calls AsyncRead on the specified channel, with a stream listener that
|
||||
// writes data to the specified output stream.
|
||||
//
|
||||
inline nsresult
|
||||
NS_AsyncReadToStream(nsIChannel *aChannel,
|
||||
nsIOutputStream *aSink,
|
||||
nsIStreamObserver *aObserver=NULL,
|
||||
nsISupports *aContext=NULL)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aChannel);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
rv = NS_NewSimpleStreamListener(getter_AddRefs(listener),
|
||||
aSink,
|
||||
aObserver);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return aChannel->AsyncRead(listener, aContext);
|
||||
}
|
||||
|
||||
#endif // nsNetUtil_h__
|
||||
|
|
|
@ -34,13 +34,16 @@ CPPSRCS = \
|
|||
nsURLHelper.cpp \
|
||||
nsFileStreams.cpp \
|
||||
nsBufferedStreams.cpp \
|
||||
nsAsyncStreamListener.cpp \
|
||||
nsSyncStreamListener.cpp \
|
||||
nsIOService.cpp \
|
||||
nsSocketTransport.cpp \
|
||||
nsSocketTransportService.cpp \
|
||||
nsFileTransport.cpp \
|
||||
nsFileTransportService.cpp \
|
||||
nsSimpleStreamListener.cpp \
|
||||
nsSimpleStreamProvider.cpp \
|
||||
nsStreamObserverProxy.cpp \
|
||||
nsStreamListenerProxy.cpp \
|
||||
nsStreamProviderProxy.cpp \
|
||||
nsStdURLParser.cpp \
|
||||
nsAuthURLParser.cpp \
|
||||
nsNoAuthURLParser.cpp \
|
||||
|
@ -55,6 +58,7 @@ CPPSRCS = \
|
|||
nsDownloader.cpp \
|
||||
nsProtocolProxyService.cpp \
|
||||
nsProxyAutoConfigUtils.cpp \
|
||||
nsAsyncStreamListener.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
|
|
|
@ -30,13 +30,16 @@ CPP_OBJS = \
|
|||
.\$(OBJDIR)\nsURLHelper.obj \
|
||||
.\$(OBJDIR)\nsFileStreams.obj \
|
||||
.\$(OBJDIR)\nsBufferedStreams.obj \
|
||||
.\$(OBJDIR)\nsAsyncStreamListener.obj \
|
||||
.\$(OBJDIR)\nsSyncStreamListener.obj \
|
||||
.\$(OBJDIR)\nsIOService.obj \
|
||||
.\$(OBJDIR)\nsSocketTransport.obj \
|
||||
.\$(OBJDIR)\nsSocketTransportService.obj \
|
||||
.\$(OBJDIR)\nsFileTransport.obj \
|
||||
.\$(OBJDIR)\nsFileTransportService.obj \
|
||||
.\$(OBJDIR)\nsSimpleStreamListener.obj \
|
||||
.\$(OBJDIR)\nsSimpleStreamProvider.obj \
|
||||
.\$(OBJDIR)\nsStreamObserverProxy.obj \
|
||||
.\$(OBJDIR)\nsStreamListenerProxy.obj \
|
||||
.\$(OBJDIR)\nsStreamProviderProxy.obj \
|
||||
.\$(OBJDIR)\nsStdURLParser.obj \
|
||||
.\$(OBJDIR)\nsAuthURLParser.obj \
|
||||
.\$(OBJDIR)\nsNoAuthURLParser.obj \
|
||||
|
|
|
@ -36,6 +36,12 @@ static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
|
|||
PRLogModuleInfo* gStreamEventLog = 0;
|
||||
#endif
|
||||
|
||||
// prevent name conflicts
|
||||
#define nsStreamListenerEvent nsStreamListenerEvent0
|
||||
#define nsOnStartRequestEvent nsOnStartRequestEvent0
|
||||
#define nsOnStopRequestEvent nsOnStopRequestEvent0
|
||||
#define nsOnDataAvailableEvent nsOnDataAvailableEvent0
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsStreamListenerEvent
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -32,6 +32,7 @@
|
|||
#include "nsILoadGroup.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
@ -41,19 +42,20 @@
|
|||
#include "prlog.h"
|
||||
#include "nsFileTransportService.h"
|
||||
|
||||
//#define TIMING
|
||||
|
||||
class nsIInterfaceRequestor;
|
||||
|
||||
class nsFileTransportSourceWrapper;
|
||||
class nsFileTransportSinkWrapper;
|
||||
|
||||
class nsFileTransport : public nsIChannel,
|
||||
public nsIRunnable,
|
||||
public nsIInputStreamObserver,
|
||||
public nsIOutputStreamObserver
|
||||
public nsIRunnable
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIINPUTSTREAMOBSERVER
|
||||
NS_DECL_NSIOUTPUTSTREAMOBSERVER
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
nsFileTransport();
|
||||
|
@ -99,7 +101,7 @@ protected:
|
|||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsIProgressEventSink> mProgress;
|
||||
nsCOMPtr<nsIStreamIO> mStreamIO;
|
||||
char* mContentType;
|
||||
char *mContentType;
|
||||
PRUint32 mBufferSegmentSize;
|
||||
PRUint32 mBufferMaxSize;
|
||||
|
||||
|
@ -107,11 +109,16 @@ protected:
|
|||
|
||||
// mXferState is only changed by the file transport thread:
|
||||
XferState mXferState;
|
||||
|
||||
// mRunState is only changed by the user's thread, but looked at by the
|
||||
// file transport thread:
|
||||
RunState mRunState;
|
||||
nsresult mCancelStatus;
|
||||
PRMonitor* mMonitor;
|
||||
PRInt32 mSuspendCount;
|
||||
PRLock *mLock;
|
||||
|
||||
// The transport is active if it is currently being processed by a thread.
|
||||
PRBool mActive;
|
||||
|
||||
// state variables:
|
||||
nsresult mStatus;
|
||||
|
@ -120,18 +127,22 @@ protected:
|
|||
PRInt32 mTransferAmount;
|
||||
nsLoadFlags mLoadAttributes;
|
||||
|
||||
// reading state varialbles:
|
||||
// reading state variables:
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
nsCOMPtr<nsIInputStream> mSource;
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
nsCOMPtr<nsIOutputStream> mOutputStream;
|
||||
nsFileTransportSourceWrapper *mSourceWrapper;
|
||||
|
||||
// writing state variables:
|
||||
nsCOMPtr<nsIStreamObserver> mObserver;
|
||||
nsCOMPtr<nsIStreamProvider> mProvider;
|
||||
nsCOMPtr<nsIOutputStream> mSink;
|
||||
char* mBuffer;
|
||||
nsFileTransportSinkWrapper *mSinkWrapper;
|
||||
|
||||
nsCString mStreamName;
|
||||
nsFileTransportService* mService;
|
||||
nsFileTransportService *mService;
|
||||
|
||||
#ifdef TIMING
|
||||
PRIntervalTime mStartTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NS_FILE_TRANSPORT_DEFAULT_SEGMENT_SIZE (2*1024)
|
||||
|
|
|
@ -170,12 +170,18 @@ nsStreamIOChannel::Init(nsIURI* uri, nsIStreamIO* io)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS5(nsStreamIOChannel,
|
||||
nsIStreamIOChannel,
|
||||
nsIChannel,
|
||||
nsIRequest,
|
||||
nsIStreamObserver,
|
||||
nsIStreamListener);
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsStreamIOChannel)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsStreamIOChannel)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsStreamIOChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamIOChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIChannel)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequest)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamProvider)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIStreamObserver, nsIStreamListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequest methods:
|
||||
|
@ -349,13 +355,12 @@ nsStreamIOChannel::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamIOChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer, nsISupports *ctxt)
|
||||
nsStreamIOChannel::AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ASSERTION(observer, "no observer");
|
||||
mUserObserver = observer;
|
||||
NS_ASSERTION(provider, "no provider");
|
||||
SetProvider(provider);
|
||||
|
||||
if (mLoadGroup) {
|
||||
nsCOMPtr<nsILoadGroupListenerFactory> factory;
|
||||
|
@ -364,12 +369,15 @@ nsStreamIOChannel::AsyncWrite(nsIInputStream *fromStream,
|
|||
//
|
||||
rv = mLoadGroup->GetGroupListenerFactory(getter_AddRefs(factory));
|
||||
if (factory) {
|
||||
NS_WARNING("load group proxy listener not implemented for AsyncWrite");
|
||||
#if 0
|
||||
nsIStreamListener *newListener;
|
||||
rv = factory->CreateLoadGroupListener(GetListener(), &newListener);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mUserObserver = newListener;
|
||||
NS_RELEASE(newListener);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rv = mLoadGroup->AddChannel(this, nsnull);
|
||||
|
@ -398,7 +406,7 @@ nsStreamIOChannel::AsyncWrite(nsIInputStream *fromStream,
|
|||
if (NS_FAILED(rv)) goto done;
|
||||
}
|
||||
#endif
|
||||
rv = mFileTransport->AsyncWrite(fromStream, this, ctxt);
|
||||
rv = mFileTransport->AsyncWrite(this, ctxt);
|
||||
|
||||
done:
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -600,7 +608,7 @@ nsStreamIOChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIStreamListener methods:
|
||||
// nsIStreamObserver implementation:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -635,6 +643,10 @@ nsStreamIOChannel::OnStopRequest(nsIChannel* transportChannel, nsISupports* cont
|
|||
return mStreamIO->Close(aStatus);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIStreamListener implementation:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamIOChannel::OnDataAvailable(nsIChannel* transportChannel, nsISupports* context,
|
||||
nsIInputStream *aIStream, PRUint32 aSourceOffset,
|
||||
|
@ -645,3 +657,16 @@ nsStreamIOChannel::OnDataAvailable(nsIChannel* transportChannel, nsISupports* co
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIStreamProvider implementation:
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamIOChannel::OnDataWritable(nsIChannel* transportChannel, nsISupports* context,
|
||||
nsIOutputStream *aOStream, PRUint32 aOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
return GetProvider()->OnDataWritable(this, context, aOStream,
|
||||
aOffset, aLength);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "nsCRT.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIStreamIO.h"
|
||||
|
||||
|
@ -56,7 +57,8 @@ protected:
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsStreamIOChannel : public nsIStreamIOChannel,
|
||||
public nsIStreamListener
|
||||
public nsIStreamListener,
|
||||
public nsIStreamProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -65,6 +67,7 @@ public:
|
|||
NS_DECL_NSISTREAMIOCHANNEL
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSISTREAMPROVIDER
|
||||
|
||||
nsStreamIOChannel();
|
||||
virtual ~nsStreamIOChannel();
|
||||
|
@ -75,6 +78,8 @@ public:
|
|||
protected:
|
||||
nsIStreamListener* GetListener() { return (nsIStreamListener*)mUserObserver.get(); }
|
||||
void SetListener(nsIStreamListener* listener) { mUserObserver = listener; }
|
||||
nsIStreamProvider* GetProvider() { return (nsIStreamProvider*)mUserObserver.get(); }
|
||||
void SetProvider(nsIStreamProvider* provider) { mUserObserver = provider; }
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsSimpleStreamListener.h"
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMPL_ISUPPORTS3(nsSimpleStreamListener,
|
||||
nsISimpleStreamListener,
|
||||
nsIStreamListener,
|
||||
nsIStreamObserver)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsSimpleStreamListener::OnStartRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
return mObserver ?
|
||||
mObserver->OnStartRequest(aChannel, aContext) : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleStreamListener::OnStopRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusText)
|
||||
{
|
||||
return mObserver ?
|
||||
mObserver->OnStopRequest(aChannel, aContext, aStatus, aStatusText) : NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamListener implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsSimpleStreamListener::OnDataAvailable(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aSource,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount)
|
||||
{
|
||||
PRUint32 writeCount;
|
||||
nsresult rv = mSink->WriteFrom(aSource, aCount, &writeCount);
|
||||
//
|
||||
// Equate zero bytes read and NS_SUCCEEDED to stopping the read.
|
||||
//
|
||||
if (NS_SUCCEEDED(rv) && (writeCount == 0))
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsISimpleStreamListener implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsSimpleStreamListener::Init(nsIOutputStream *aSink,
|
||||
nsIStreamObserver *aObserver)
|
||||
{
|
||||
NS_PRECONDITION(aSink, "null output stream");
|
||||
|
||||
mSink = aSink;
|
||||
mObserver = aObserver;
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#include "nsIStreamListener.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsSimpleStreamListener : public nsISimpleStreamListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSISIMPLESTREAMLISTENER
|
||||
|
||||
nsSimpleStreamListener() { NS_INIT_ISUPPORTS(); }
|
||||
virtual ~nsSimpleStreamListener() {}
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIOutputStream> mSink;
|
||||
nsCOMPtr<nsIStreamObserver> mObserver;
|
||||
};
|
|
@ -0,0 +1,96 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsSimpleStreamProvider.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMPL_ISUPPORTS3(nsSimpleStreamProvider,
|
||||
nsISimpleStreamProvider,
|
||||
nsIStreamProvider,
|
||||
nsIStreamObserver)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsSimpleStreamProvider::OnStartRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
return mObserver ?
|
||||
mObserver->OnStartRequest(aChannel, aContext) : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSimpleStreamProvider::OnStopRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusText)
|
||||
{
|
||||
return mObserver ?
|
||||
mObserver->OnStopRequest(aChannel, aContext, aStatus, aStatusText) : NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamProvider implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsSimpleStreamProvider::OnDataWritable(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsIOutputStream *aOutput,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount)
|
||||
{
|
||||
PRUint32 writeCount;
|
||||
nsresult rv = aOutput->WriteFrom(mSource, aCount, &writeCount);
|
||||
//
|
||||
// Equate zero bytes written and NS_SUCCEEDED to EOF
|
||||
//
|
||||
if (NS_SUCCEEDED(rv) && (writeCount == 0))
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsISimpleStreamProvider implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsSimpleStreamProvider::Init(nsIInputStream *aSource,
|
||||
nsIStreamObserver *aObserver)
|
||||
{
|
||||
NS_PRECONDITION(aSource, "null input stream");
|
||||
|
||||
mSource = aSource;
|
||||
mObserver = aObserver;
|
||||
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#include "nsIStreamProvider.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsSimpleStreamProvider : public nsISimpleStreamProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSISTREAMPROVIDER
|
||||
NS_DECL_NSISIMPLESTREAMPROVIDER
|
||||
|
||||
nsSimpleStreamProvider() { NS_INIT_ISUPPORTS(); }
|
||||
virtual ~nsSimpleStreamProvider() {}
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIInputStream> mSource;
|
||||
nsCOMPtr<nsIStreamObserver> mObserver;
|
||||
};
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -35,6 +35,7 @@
|
|||
#include "nsIOutputStream.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsIDNSListener.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
|
@ -114,6 +115,8 @@ enum nsSocketReadWriteInfo {
|
|||
|
||||
// Forward declarations...
|
||||
class nsSocketTransportService;
|
||||
class nsSocketInputStream;
|
||||
class nsSocketOutputStream;
|
||||
class nsIInterfaceRequestor;
|
||||
|
||||
class nsSocketTransport : public nsISocketTransport,
|
||||
|
@ -166,7 +169,9 @@ protected:
|
|||
nsresult doConnection(PRInt16 aSelectFlags);
|
||||
nsresult doResolveHost(void);
|
||||
nsresult doRead(PRInt16 aSelectFlags);
|
||||
nsresult doReadAsync(PRInt16 aSelectFlags);
|
||||
nsresult doWrite(PRInt16 aSelectFlags);
|
||||
nsresult doWriteAsync(PRInt16 aSelectFlags);
|
||||
|
||||
nsresult doWriteFromBuffer(PRUint32 *aCount);
|
||||
nsresult doWriteFromStream(PRUint32 *aCount);
|
||||
|
@ -222,40 +227,41 @@ protected:
|
|||
nsSocketOperation mOperation;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsISupports> mSecurityInfo;
|
||||
|
||||
PRInt32 mProxyPort;
|
||||
char* mProxyHost;
|
||||
PRBool mProxyTransparent;
|
||||
PRBool mSSLProxy;
|
||||
nsCOMPtr<nsISupports> mReadContext;
|
||||
nsCOMPtr<nsIStreamListener> mReadListener;
|
||||
nsCOMPtr<nsIInputStream> mReadPipeIn;
|
||||
nsCOMPtr<nsIOutputStream> mReadPipeOut;
|
||||
|
||||
nsSocketTransportService* mService;
|
||||
|
||||
PRUint32 mReadWriteState;
|
||||
PRInt16 mSelectFlags;
|
||||
nsSocketTransportService* mService;
|
||||
nsresult mStatus;
|
||||
PRInt32 mSuspendCount;
|
||||
|
||||
PRFileDesc* mSocketFD;
|
||||
PRUint32 mSocketTypeCount;
|
||||
char* *mSocketTypes;
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mReadListener;
|
||||
nsCOMPtr<nsISupports> mReadContext;
|
||||
PRUint32 mReadOffset;
|
||||
PRUint32 mWriteOffset;
|
||||
nsresult mStatus;
|
||||
PRInt32 mSuspendCount;
|
||||
PRInt32 mWriteCount;
|
||||
|
||||
nsCOMPtr<nsIStreamProvider> mWriteProvider;
|
||||
nsCOMPtr<nsISupports> mWriteContext;
|
||||
PRInt32 mBytesExpected;
|
||||
PRUint32 mWriteOffset;
|
||||
PRInt32 mWriteCount;
|
||||
|
||||
PRInt32 mBytesExpected;
|
||||
PRUint32 mReuseCount;
|
||||
PRUint32 mLastReuseCount;
|
||||
|
||||
nsSocketInputStream *mSocketInputStream;
|
||||
nsSocketOutputStream *mSocketOutputStream;
|
||||
|
||||
// The following four members are used when AsyncWrite(...) is called
|
||||
// with an nsIInputStream which does not also support the
|
||||
// nsIBufferedInputStream interface...
|
||||
//
|
||||
nsCOMPtr<nsIInputStream> mWriteFromStream;
|
||||
char * mWriteBuffer;
|
||||
PRUint32 mWriteBufferIndex;
|
||||
PRUint32 mWriteBufferLength;
|
||||
|
||||
nsCOMPtr<nsIStreamObserver> mWriteObserver;
|
||||
nsCOMPtr<nsIInputStream> mReadPipeIn;
|
||||
nsCOMPtr<nsIOutputStream> mReadPipeOut;
|
||||
nsCOMPtr<nsIInputStream> mWritePipeIn;
|
||||
nsCOMPtr<nsIOutputStream> mWritePipeOut;
|
||||
PRUint32 mBufferSegmentSize;
|
||||
|
|
|
@ -0,0 +1,395 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsStreamListenerProxy.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsAutoLock.h"
|
||||
|
||||
#define LOG(args) PR_LOG(gStreamProxyLog, PR_LOG_DEBUG, args)
|
||||
|
||||
#define DEFAULT_BUFFER_SEGMENT_SIZE 2048
|
||||
#define DEFAULT_BUFFER_MAX_SIZE (4*2048)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Design Overview
|
||||
//
|
||||
// A stream listener proxy maintains a pipe. When the channel makes data
|
||||
// available, the proxy copies as much of that data as possible into the pipe.
|
||||
// If data was written to the pipe, then the proxy posts an asynchronous event
|
||||
// corresponding to the amount of data written. If no data could be written,
|
||||
// because the pipe was full, then WOULD_BLOCK is returned to the channel,
|
||||
// indicating that the channel should suspend itself.
|
||||
//
|
||||
// Once suspended in this manner, the channel is only resumed when the pipe is
|
||||
// emptied.
|
||||
//
|
||||
// XXX The current design does NOT allow the channel to be "externally"
|
||||
// suspended!! For the moment this is not a problem, but it should be fixed.
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamListenerProxy implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
nsStreamListenerProxy::nsStreamListenerProxy()
|
||||
: mLock(nsnull)
|
||||
, mPendingCount(0)
|
||||
, mListenerStatus(NS_OK)
|
||||
{ }
|
||||
|
||||
nsStreamListenerProxy::~nsStreamListenerProxy()
|
||||
{
|
||||
if (mLock) {
|
||||
PR_DestroyLock(mLock);
|
||||
mLock = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsStreamListenerProxy::GetPendingCount()
|
||||
{
|
||||
return PR_AtomicSet((PRInt32 *) &mPendingCount, 0);
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsOnDataAvailableEvent internal class...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
class nsOnDataAvailableEvent : public nsStreamObserverEvent
|
||||
{
|
||||
public:
|
||||
nsOnDataAvailableEvent(nsStreamProxyBase *aProxy,
|
||||
nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aSource,
|
||||
PRUint32 aOffset)
|
||||
: nsStreamObserverEvent(aProxy, aChannel, aContext)
|
||||
, mSource(aSource)
|
||||
, mOffset(aOffset)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsOnDataAvailableEvent);
|
||||
}
|
||||
|
||||
~nsOnDataAvailableEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsOnDataAvailableEvent);
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleEvent();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIInputStream> mSource;
|
||||
PRUint32 mOffset;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnDataAvailableEvent::HandleEvent()
|
||||
{
|
||||
LOG(("nsOnDataAvailableEvent: HandleEvent [event=%x, chan=%x]", this, mChannel.get()));
|
||||
|
||||
nsStreamListenerProxy *listenerProxy =
|
||||
NS_STATIC_CAST(nsStreamListenerProxy *, mProxy);
|
||||
|
||||
if (NS_FAILED(listenerProxy->GetListenerStatus())) {
|
||||
LOG(("nsOnDataAvailableEvent: Discarding event [listener_status=%x, chan=%x]\n",
|
||||
listenerProxy->GetListenerStatus(), mChannel.get()));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStreamListener> listener = listenerProxy->GetListener();
|
||||
if (!listener) {
|
||||
LOG(("nsOnDataAvailableEvent: Already called OnStopRequest (listener is NULL), [chan=%x]\n",
|
||||
mChannel.get()));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult status = NS_OK;
|
||||
nsresult rv = mChannel->GetStatus(&status);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||
|
||||
//
|
||||
// We should only forward this event to the listener if the channel is
|
||||
// still in a "good" state. Because these events are being processed
|
||||
// asynchronously, there is a very real chance that the listener might
|
||||
// have cancelled the channel after _this_ event was triggered.
|
||||
//
|
||||
if (NS_SUCCEEDED(status)) {
|
||||
//
|
||||
// Find out from the listener proxy how many bytes to report.
|
||||
//
|
||||
PRUint32 count = listenerProxy->GetPendingCount();
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
{
|
||||
PRUint32 avail;
|
||||
mSource->Available(&avail);
|
||||
LOG(("nsOnDataAvailableEvent: Calling the consumer's OnDataAvailable "
|
||||
"[offset=%u count=%u avail=%u chan=%x]\n",
|
||||
mOffset, count, avail, mChannel.get()));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Forward call to listener
|
||||
rv = listener->OnDataAvailable(mChannel, mContext, mSource, mOffset, count);
|
||||
|
||||
LOG(("nsOnDataAvailableEvent: Done with the consumer's OnDataAvailable "
|
||||
"[rv=%x, chan=%x]\n",
|
||||
rv, mChannel.get()));
|
||||
|
||||
//
|
||||
// XXX Need to suspend the underlying channel... must consider
|
||||
// other pending events (such as OnStopRequest). These
|
||||
// should not be forwarded to the listener if the channel
|
||||
// is suspended. Also, handling the Resume could be tricky.
|
||||
//
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
NS_NOTREACHED("listener returned NS_BASE_STREAM_WOULD_BLOCK"
|
||||
" -- support for this is not implemented");
|
||||
rv = NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
//
|
||||
// Update the listener status
|
||||
//
|
||||
listenerProxy->SetListenerStatus(rv);
|
||||
}
|
||||
else
|
||||
LOG(("nsOnDataAvailableEvent: Not calling OnDataAvailable [chan=%x]",
|
||||
mChannel.get()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMPL_ISUPPORTS_INHERITED3(nsStreamListenerProxy,
|
||||
nsStreamProxyBase,
|
||||
nsIStreamListenerProxy,
|
||||
nsIStreamListener,
|
||||
nsIInputStreamObserver)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnStartRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
|
||||
return nsStreamProxyBase::OnStartRequest(aChannel, aContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnStopRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusText)
|
||||
{
|
||||
//
|
||||
// We are done with the pipe.
|
||||
//
|
||||
mPipeIn = 0;
|
||||
mPipeOut = 0;
|
||||
|
||||
return nsStreamProxyBase::OnStopRequest(aChannel, aContext,
|
||||
aStatus, aStatusText);
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamListener implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnDataAvailable(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsIInputStream *aSource,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 bytesWritten=0;
|
||||
|
||||
LOG(("nsStreamListenerProxy: OnDataAvailable [offset=%u count=%u chan=%x]\n",
|
||||
aOffset, aCount, aChannel));
|
||||
|
||||
NS_PRECONDITION(mChannelToResume == 0, "Unexpected call to OnDataAvailable");
|
||||
NS_PRECONDITION(mPipeIn, "Pipe not initialized");
|
||||
NS_PRECONDITION(mPipeOut, "Pipe not initialized");
|
||||
|
||||
//
|
||||
// Any non-successful listener status gets passed back to the caller
|
||||
//
|
||||
{
|
||||
nsresult status = mListenerStatus;
|
||||
if (NS_FAILED(status)) {
|
||||
LOG(("nsStreamListenerProxy: Listener failed [status=%x chan=%x]\n", status, aChannel));
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Enter the ChannelToResume lock
|
||||
//
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
|
||||
//
|
||||
// Try to copy data into the pipe.
|
||||
//
|
||||
// If the pipe is full, then suspend the calling channel. It
|
||||
// will be resumed when the pipe is emptied. Being inside the
|
||||
// ChannelToResume lock ensures that the resume will follow
|
||||
// the suspend.
|
||||
//
|
||||
rv = mPipeOut->WriteFrom(aSource, aCount, &bytesWritten);
|
||||
|
||||
LOG(("nsStreamListenerProxy: Wrote data to pipe [rv=%x count=%u bytesWritten=%u chan=%x]\n",
|
||||
rv, aCount, bytesWritten, aChannel));
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
LOG(("nsStreamListenerProxy: Setting channel to resume [chan=%x]\n", aChannel));
|
||||
mChannelToResume = aChannel;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
else if (bytesWritten == 0) {
|
||||
LOG(("nsStreamListenerProxy: Copied zero bytes; not posting an event [chan=%x]\n", aChannel));
|
||||
return NS_BASE_STREAM_CLOSED; // there was no more data to read!
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Update the pending count; return if able to piggy-back on a pending event.
|
||||
//
|
||||
PRUint32 total = PR_AtomicAdd((PRInt32 *) &mPendingCount, bytesWritten);
|
||||
if (total > bytesWritten) {
|
||||
LOG(("nsStreamListenerProxy: Piggy-backing pending event [total=%u, chan=%x]\n",
|
||||
total, aChannel));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Post an event for the number of bytes actually written.
|
||||
//
|
||||
nsOnDataAvailableEvent *ev =
|
||||
new nsOnDataAvailableEvent(this, aChannel, aContext, mPipeIn, aOffset);
|
||||
if (!ev) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = ev->FireEvent(GetEventQueue());
|
||||
if (NS_FAILED(rv)) {
|
||||
delete ev;
|
||||
return rv;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamListenerProxy implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::Init(nsIStreamListener *aListener,
|
||||
nsIEventQueue *aEventQ,
|
||||
PRUint32 aBufferSegmentSize,
|
||||
PRUint32 aBufferMaxSize)
|
||||
{
|
||||
NS_PRECONDITION(GetReceiver() == nsnull, "Listener already set");
|
||||
NS_PRECONDITION(GetEventQueue() == nsnull, "Event queue already set");
|
||||
|
||||
//
|
||||
// Create the ChannelToResume lock
|
||||
//
|
||||
mLock = PR_NewLock();
|
||||
if (!mLock) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
//
|
||||
// Create the pipe
|
||||
//
|
||||
if (aBufferSegmentSize == 0)
|
||||
aBufferSegmentSize = DEFAULT_BUFFER_SEGMENT_SIZE;
|
||||
if (aBufferMaxSize == 0)
|
||||
aBufferMaxSize = DEFAULT_BUFFER_MAX_SIZE;
|
||||
// The segment size must not exceed the maximum
|
||||
aBufferSegmentSize = PR_MIN(aBufferMaxSize, aBufferSegmentSize);
|
||||
|
||||
nsresult rv = NS_NewPipe(getter_AddRefs(mPipeIn),
|
||||
getter_AddRefs(mPipeOut),
|
||||
aBufferSegmentSize,
|
||||
aBufferMaxSize,
|
||||
PR_TRUE, PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = mPipeIn->SetObserver(this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
SetReceiver(aListener);
|
||||
return SetEventQueue(aEventQ);
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIInputStreamObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnEmpty(nsIInputStream *aInputStream)
|
||||
{
|
||||
LOG(("nsStreamListenerProxy: OnEmpty\n"));
|
||||
//
|
||||
// The pipe has been emptied by the listener. If the channel
|
||||
// has been suspended (waiting for the pipe to be emptied), then
|
||||
// go ahead and resume it. But take care not to resume while
|
||||
// holding the "ChannelToResume" lock.
|
||||
//
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
{
|
||||
nsAutoLock lock(mLock);
|
||||
chan = mChannelToResume;
|
||||
mChannelToResume = 0;
|
||||
}
|
||||
if (chan) {
|
||||
LOG(("nsStreamListenerProxy: Resuming channel\n"));
|
||||
chan->Resume();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamListenerProxy::OnClose(nsIInputStream *aInputStream)
|
||||
{
|
||||
LOG(("nsStreamListenerProxy: OnClose\n"));
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef nsStreamListenerProxy_h__
|
||||
#define nsStreamListenerProxy_h__
|
||||
|
||||
#include "nsStreamObserverProxy.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsStreamListenerProxy : public nsStreamProxyBase
|
||||
, public nsIStreamListenerProxy
|
||||
, public nsIInputStreamObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSISTREAMLISTENERPROXY
|
||||
NS_DECL_NSIINPUTSTREAMOBSERVER
|
||||
|
||||
nsStreamListenerProxy();
|
||||
virtual ~nsStreamListenerProxy();
|
||||
|
||||
nsIStreamListener *GetListener()
|
||||
{
|
||||
return NS_STATIC_CAST(nsIStreamListener *, GetReceiver());
|
||||
}
|
||||
|
||||
void SetListenerStatus(nsresult status)
|
||||
{
|
||||
mListenerStatus = status;
|
||||
}
|
||||
|
||||
nsresult GetListenerStatus()
|
||||
{
|
||||
return mListenerStatus;
|
||||
}
|
||||
|
||||
PRUint32 GetPendingCount();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIInputStream> mPipeIn;
|
||||
nsCOMPtr<nsIOutputStream> mPipeOut;
|
||||
nsCOMPtr<nsIChannel> mChannelToResume;
|
||||
PRLock *mLock;
|
||||
PRUint32 mPendingCount;
|
||||
nsresult mListenerStatus;
|
||||
};
|
||||
|
||||
#endif /* !nsStreamListenerProxy_h__ */
|
|
@ -0,0 +1,274 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsStreamObserverProxy.h"
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsString.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
PRLogModuleInfo *gStreamProxyLog;
|
||||
#endif
|
||||
#define LOG(args) PR_LOG(gStreamProxyLog, PR_LOG_DEBUG, args)
|
||||
|
||||
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamObserverEvent implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
nsStreamObserverEvent::nsStreamObserverEvent(nsStreamProxyBase *aProxy,
|
||||
nsIChannel *aChannel,
|
||||
nsISupports *aContext)
|
||||
: mProxy(aProxy)
|
||||
, mChannel(aChannel)
|
||||
, mContext(aContext)
|
||||
{
|
||||
NS_IF_ADDREF(mProxy);
|
||||
}
|
||||
|
||||
nsStreamObserverEvent::~nsStreamObserverEvent()
|
||||
{
|
||||
NS_IF_RELEASE(mProxy);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsStreamObserverEvent::FireEvent(nsIEventQueue *aEventQ)
|
||||
{
|
||||
NS_PRECONDITION(aEventQ, "null event queue");
|
||||
|
||||
PL_InitEvent(&mEvent, nsnull,
|
||||
(PLHandleEventProc) nsStreamObserverEvent::HandlePLEvent,
|
||||
(PLDestroyEventProc) nsStreamObserverEvent::DestroyPLEvent);
|
||||
|
||||
PRStatus status = aEventQ->PostEvent(&mEvent);
|
||||
return status == PR_SUCCESS ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void PR_CALLBACK
|
||||
nsStreamObserverEvent::HandlePLEvent(PLEvent *aEvent)
|
||||
{
|
||||
nsStreamObserverEvent *ev = GET_STREAM_OBSERVER_EVENT(aEvent);
|
||||
NS_ASSERTION(ev, "null event");
|
||||
|
||||
// Pass control the real event handler
|
||||
if (ev)
|
||||
ev->HandleEvent();
|
||||
}
|
||||
|
||||
void PR_CALLBACK
|
||||
nsStreamObserverEvent::DestroyPLEvent(PLEvent *aEvent)
|
||||
{
|
||||
nsStreamObserverEvent *ev = GET_STREAM_OBSERVER_EVENT(aEvent);
|
||||
NS_ASSERTION(ev, "null event");
|
||||
delete ev;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsOnStartRequestEvent internal class...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
class nsOnStartRequestEvent : public nsStreamObserverEvent
|
||||
{
|
||||
public:
|
||||
nsOnStartRequestEvent(nsStreamProxyBase *aProxy,
|
||||
nsIChannel *aChannel,
|
||||
nsISupports *aContext)
|
||||
: nsStreamObserverEvent(aProxy, aChannel, aContext)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsOnStartRequestEvent);
|
||||
}
|
||||
|
||||
~nsOnStartRequestEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsOnStartRequestEvent);
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleEvent();
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnStartRequestEvent::HandleEvent()
|
||||
{
|
||||
LOG(("nsOnStartRequestEvent: HandleEvent [event=%x chan=%x]\n",
|
||||
this, mChannel.get()));
|
||||
|
||||
nsCOMPtr<nsIStreamObserver> observer = mProxy->GetReceiver();
|
||||
if (!observer) {
|
||||
LOG(("nsOnStartRequestEvent: Already called OnStopRequest (observer is NULL)\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return observer->OnStartRequest(mChannel, mContext);
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsOnStopRequestEvent internal class...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
class nsOnStopRequestEvent : public nsStreamObserverEvent
|
||||
{
|
||||
public:
|
||||
nsOnStopRequestEvent(nsStreamProxyBase *aProxy,
|
||||
nsIChannel *aChannel, nsISupports *aContext,
|
||||
nsresult aStatus, const PRUnichar *aStatusText)
|
||||
: nsStreamObserverEvent(aProxy, aChannel, aContext)
|
||||
, mStatus(aStatus)
|
||||
, mStatusText(aStatusText)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsOnStopRequestEvent);
|
||||
}
|
||||
|
||||
~nsOnStopRequestEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsOnStopRequestEvent);
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleEvent();
|
||||
|
||||
protected:
|
||||
nsresult mStatus;
|
||||
nsString mStatusText;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnStopRequestEvent::HandleEvent()
|
||||
{
|
||||
LOG(("nsOnStopRequestEvent: HandleEvent [event=%x chan=%x]\n",
|
||||
this, mChannel.get()));
|
||||
|
||||
nsCOMPtr<nsIStreamObserver> observer = mProxy->GetReceiver();
|
||||
if (!observer) {
|
||||
LOG(("nsOnStopRequestEvent: Already called OnStopRequest (observer is NULL)\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
//
|
||||
// Do not allow any more events to be handled after OnStopRequest
|
||||
//
|
||||
mProxy->SetReceiver(nsnull);
|
||||
|
||||
return observer->OnStopRequest(mChannel,
|
||||
mContext,
|
||||
mStatus,
|
||||
mStatusText.GetUnicode());
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamProxyBase: nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS1(nsStreamProxyBase,
|
||||
nsIStreamObserver)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamProxyBase: nsIStreamObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamProxyBase::OnStartRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
LOG(("nsStreamProxyBase: OnStartRequest [this=%x chan=%x]\n", this, aChannel));
|
||||
nsOnStartRequestEvent *ev =
|
||||
new nsOnStartRequestEvent(this, aChannel, aContext);
|
||||
if (!ev)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = ev->FireEvent(GetEventQueue());
|
||||
if (NS_FAILED(rv))
|
||||
delete ev;
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamProxyBase::OnStopRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusText)
|
||||
{
|
||||
LOG(("nsStreamProxyBase: OnStopRequest [this=%x chan=%x status=%x]\n",
|
||||
this, aChannel, aStatus));
|
||||
nsOnStopRequestEvent *ev =
|
||||
new nsOnStopRequestEvent(this, aChannel, aContext, aStatus, aStatusText);
|
||||
if (!ev)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsresult rv = ev->FireEvent(GetEventQueue());
|
||||
if (NS_FAILED(rv))
|
||||
delete ev;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamProxyBase: implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
nsresult
|
||||
nsStreamProxyBase::SetEventQueue(nsIEventQueue *aEventQ)
|
||||
{
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gStreamProxyLog)
|
||||
gStreamProxyLog = PR_NewLogModule("nsStreamProxy");
|
||||
#endif
|
||||
nsresult rv = NS_OK;
|
||||
if ((aEventQ == NS_CURRENT_EVENTQ) || (aEventQ == NS_UI_THREAD_EVENTQ)) {
|
||||
nsCOMPtr<nsIEventQueueService> serv =
|
||||
do_GetService(kEventQueueService, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = serv->GetSpecialEventQueue((PRInt32) aEventQ,
|
||||
getter_AddRefs(mEventQ));
|
||||
} else
|
||||
mEventQ = aEventQ;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamObserverProxy: nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsStreamObserverProxy,
|
||||
nsStreamProxyBase,
|
||||
nsIStreamObserverProxy)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsStreamObserverProxy: nsIStreamObserverProxy implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamObserverProxy::Init(nsIStreamObserver *aObserver,
|
||||
nsIEventQueue *aEventQ)
|
||||
{
|
||||
NS_PRECONDITION(aObserver, "null observer");
|
||||
SetReceiver(aObserver);
|
||||
return SetEventQueue(aEventQ);
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsStreamObserverProxy_h__
|
||||
#define nsStreamObserverProxy_h__
|
||||
|
||||
#include "nsIStreamObserver.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
extern PRLogModuleInfo *gStreamProxyLog;
|
||||
#endif
|
||||
|
||||
class nsStreamProxyBase : public nsIStreamObserver
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
|
||||
nsStreamProxyBase() { NS_INIT_ISUPPORTS(); }
|
||||
virtual ~nsStreamProxyBase() {}
|
||||
|
||||
nsIEventQueue *GetEventQueue() { return mEventQ.get(); }
|
||||
nsIStreamObserver *GetReceiver() { return mReceiver.get(); }
|
||||
|
||||
nsresult SetEventQueue(nsIEventQueue *);
|
||||
|
||||
nsresult SetReceiver(nsIStreamObserver *aReceiver) {
|
||||
mReceiver = aReceiver;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIEventQueue> mEventQ;
|
||||
nsCOMPtr<nsIStreamObserver> mReceiver;
|
||||
};
|
||||
|
||||
class nsStreamObserverProxy : public nsStreamProxyBase
|
||||
, public nsIStreamObserverProxy
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_NSISTREAMOBSERVER(nsStreamProxyBase::)
|
||||
NS_DECL_NSISTREAMOBSERVERPROXY
|
||||
};
|
||||
|
||||
class nsStreamObserverEvent
|
||||
{
|
||||
public:
|
||||
nsStreamObserverEvent(nsStreamProxyBase *proxy,
|
||||
nsIChannel *channel, nsISupports *context);
|
||||
virtual ~nsStreamObserverEvent();
|
||||
|
||||
nsresult FireEvent(nsIEventQueue *);
|
||||
NS_IMETHOD HandleEvent() = 0;
|
||||
|
||||
protected:
|
||||
static void PR_CALLBACK HandlePLEvent(PLEvent *);
|
||||
static void PR_CALLBACK DestroyPLEvent(PLEvent *);
|
||||
|
||||
PLEvent mEvent;
|
||||
nsStreamProxyBase *mProxy;
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsISupports> mContext;
|
||||
};
|
||||
|
||||
#define GET_STREAM_OBSERVER_EVENT(_mEvent_ptr) \
|
||||
((nsStreamObserverEvent *) \
|
||||
((char *)(_mEvent_ptr) - offsetof(nsStreamObserverEvent, mEvent)))
|
||||
|
||||
#endif /* !nsStreamObserverProxy_h__ */
|
|
@ -0,0 +1,285 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsStreamProviderProxy.h"
|
||||
#include "nsIPipe.h"
|
||||
|
||||
#define LOG(args) PR_LOG(gStreamProxyLog, PR_LOG_DEBUG, args)
|
||||
|
||||
#define DEFAULT_BUFFER_SEGMENT_SIZE 2048
|
||||
#define DEFAULT_BUFFER_MAX_SIZE (4*2048)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Design Overview
|
||||
//
|
||||
// A stream provider proxy maintains a pipe. When requested to provide data
|
||||
// to the channel, whatever data is in the pipe (up to the amount requested)
|
||||
// is provided to the channel. If there is no data in the pipe, then the
|
||||
// proxy posts an asynchronous event for more data, and returns WOULD_BLOCK
|
||||
// indicating that the channel should suspend itself.
|
||||
//
|
||||
// The channel is only resumed once the event has been successfully handled;
|
||||
// meaning that data has been written to the pipe.
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
nsStreamProviderProxy::nsStreamProviderProxy()
|
||||
: mProviderStatus(NS_OK)
|
||||
{ }
|
||||
|
||||
nsStreamProviderProxy::~nsStreamProviderProxy()
|
||||
{ }
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsOnDataWritableEvent internal class...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
class nsOnDataWritableEvent : public nsStreamObserverEvent
|
||||
{
|
||||
public:
|
||||
nsOnDataWritableEvent(nsStreamProxyBase *aProxy,
|
||||
nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsIOutputStream *aSink,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount)
|
||||
: nsStreamObserverEvent(aProxy, aChannel, aContext)
|
||||
, mSink(aSink)
|
||||
, mOffset(aOffset)
|
||||
, mCount(aCount)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsOnDataWritableEvent);
|
||||
}
|
||||
|
||||
~nsOnDataWritableEvent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsOnDataWritableEvent);
|
||||
}
|
||||
|
||||
NS_IMETHOD HandleEvent();
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIOutputStream> mSink;
|
||||
PRUint32 mOffset;
|
||||
PRUint32 mCount;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOnDataWritableEvent::HandleEvent()
|
||||
{
|
||||
LOG(("nsOnDataWritableEvent: HandleEvent [event=%x chan=%x]",
|
||||
this, mChannel.get()));
|
||||
|
||||
nsStreamProviderProxy *providerProxy =
|
||||
NS_STATIC_CAST(nsStreamProviderProxy *, mProxy);
|
||||
|
||||
nsCOMPtr<nsIStreamProvider> provider = providerProxy->GetProvider();
|
||||
if (!provider) {
|
||||
LOG(("nsOnDataWritableEvent: Already called OnStopRequest (provider is NULL)\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult status = NS_OK;
|
||||
nsresult rv = mChannel->GetStatus(&status);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "GetStatus failed");
|
||||
|
||||
//
|
||||
// We should only forward this event to the provider if the channel is
|
||||
// still in a "good" state. Because these events are being processed
|
||||
// asynchronously, there is a very real chance that the provider might
|
||||
// have cancelled the channel after _this_ event was triggered.
|
||||
//
|
||||
if (NS_SUCCEEDED(status)) {
|
||||
LOG(("nsOnDataWritableEvent: Calling the consumer's OnDataWritable\n"));
|
||||
rv = provider->OnDataWritable(mChannel, mContext, mSink, mOffset, mCount);
|
||||
LOG(("nsOnDataWritableEvent: Done with the consumer's OnDataWritable [rv=%x]\n", rv));
|
||||
|
||||
//
|
||||
// Mask NS_BASE_STREAM_WOULD_BLOCK return values.
|
||||
//
|
||||
providerProxy->SetProviderStatus(
|
||||
rv != NS_BASE_STREAM_WOULD_BLOCK ? rv : NS_OK);
|
||||
|
||||
//
|
||||
// The channel is already suspended, so unless the provider returned
|
||||
// NS_BASE_STREAM_WOULD_BLOCK, we should wake up the channel.
|
||||
//
|
||||
if (rv != NS_BASE_STREAM_WOULD_BLOCK)
|
||||
mChannel->Resume();
|
||||
}
|
||||
else
|
||||
LOG(("nsOnDataWritableEvent: Not calling OnDataWritable"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsISupports implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMPL_ISUPPORTS_INHERITED2(nsStreamProviderProxy,
|
||||
nsStreamProxyBase,
|
||||
nsIStreamProviderProxy,
|
||||
nsIStreamProvider)
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamObserver implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamProviderProxy::OnStartRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
return nsStreamProxyBase::OnStartRequest(aChannel, aContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamProviderProxy::OnStopRequest(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsresult aStatus,
|
||||
const PRUnichar *aStatusText)
|
||||
{
|
||||
//
|
||||
// Close the pipe
|
||||
//
|
||||
mPipeIn = 0;
|
||||
mPipeOut = 0;
|
||||
|
||||
return nsStreamProxyBase::OnStopRequest(aChannel, aContext,
|
||||
aStatus, aStatusText);
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamProvider implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
static NS_METHOD
|
||||
nsWriteToSink(nsIInputStream *source,
|
||||
void *closure,
|
||||
const char *fromRawSegment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
nsIOutputStream *sink = (nsIOutputStream *) closure;
|
||||
return sink->Write(fromRawSegment, count, writeCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsStreamProviderProxy::OnDataWritable(nsIChannel *aChannel,
|
||||
nsISupports *aContext,
|
||||
nsIOutputStream *aSink,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
LOG(("nsStreamProviderProxy: OnDataWritable [offset=%u, count=%u]\n",
|
||||
aOffset, aCount));
|
||||
|
||||
NS_PRECONDITION(aCount > 0, "Invalid parameter");
|
||||
NS_PRECONDITION(mPipeIn, "Pipe not initialized");
|
||||
NS_PRECONDITION(mPipeOut, "Pipe not initialized");
|
||||
NS_PRECONDITION(mProviderStatus != NS_BASE_STREAM_WOULD_BLOCK,
|
||||
"Invalid provider status");
|
||||
|
||||
//
|
||||
// Any non-successful provider status gets passed back to the caller
|
||||
//
|
||||
if (NS_FAILED(mProviderStatus)) {
|
||||
LOG(("nsStreamProviderProxy: Provider failed [status=%x]\n", mProviderStatus));
|
||||
return mProviderStatus;
|
||||
}
|
||||
|
||||
//
|
||||
// Provide the channel with whatever data is already in the pipe (not
|
||||
// exceeding aCount).
|
||||
//
|
||||
PRUint32 count;
|
||||
rv = mPipeIn->Available(&count);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (count > 0) {
|
||||
count = PR_MIN(count, aCount);
|
||||
|
||||
PRUint32 bytesWritten;
|
||||
rv = mPipeIn->ReadSegments(nsWriteToSink, aSink, count, &bytesWritten);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// Post an event requesting the provider for more data.
|
||||
//
|
||||
nsOnDataWritableEvent *ev =
|
||||
new nsOnDataWritableEvent(this, aChannel, aContext,
|
||||
mPipeOut, aOffset, aCount);
|
||||
if (!ev)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = ev->FireEvent(GetEventQueue());
|
||||
if (NS_FAILED(rv)) {
|
||||
delete ev;
|
||||
return rv;
|
||||
}
|
||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// nsIStreamProviderProxy implementation...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsStreamProviderProxy::Init(nsIStreamProvider *aProvider,
|
||||
nsIEventQueue *aEventQ,
|
||||
PRUint32 aBufferSegmentSize,
|
||||
PRUint32 aBufferMaxSize)
|
||||
{
|
||||
NS_PRECONDITION(GetReceiver() == nsnull, "Listener already set");
|
||||
NS_PRECONDITION(GetEventQueue() == nsnull, "Event queue already set");
|
||||
|
||||
//
|
||||
// Create the pipe
|
||||
//
|
||||
if (aBufferSegmentSize == 0)
|
||||
aBufferSegmentSize = DEFAULT_BUFFER_SEGMENT_SIZE;
|
||||
if (aBufferMaxSize == 0)
|
||||
aBufferMaxSize = DEFAULT_BUFFER_MAX_SIZE;
|
||||
// The segment size must not exceed the maximum
|
||||
aBufferSegmentSize = PR_MIN(aBufferMaxSize, aBufferSegmentSize);
|
||||
|
||||
nsresult rv = NS_NewPipe(getter_AddRefs(mPipeIn),
|
||||
getter_AddRefs(mPipeOut),
|
||||
aBufferSegmentSize,
|
||||
aBufferMaxSize,
|
||||
PR_TRUE, PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
SetReceiver(aProvider);
|
||||
return SetEventQueue(aEventQ);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef nsStreamProviderProxy_h__
|
||||
#define nsStreamProviderProxy_h__
|
||||
|
||||
#include "nsStreamObserverProxy.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
||||
class nsStreamProviderProxy : public nsStreamProxyBase
|
||||
, public nsIStreamProviderProxy
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSISTREAMPROVIDER
|
||||
NS_DECL_NSISTREAMPROVIDERPROXY
|
||||
|
||||
nsStreamProviderProxy();
|
||||
virtual ~nsStreamProviderProxy();
|
||||
|
||||
nsIStreamProvider *GetProvider()
|
||||
{
|
||||
return NS_STATIC_CAST(nsIStreamProvider *, GetReceiver());
|
||||
}
|
||||
|
||||
void SetProviderStatus(nsresult status)
|
||||
{
|
||||
mProviderStatus = status;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIInputStream> mPipeIn;
|
||||
nsCOMPtr<nsIOutputStream> mPipeOut;
|
||||
nsresult mProviderStatus;
|
||||
};
|
||||
|
||||
#endif /* !nsStreamProviderProxy_h__ */
|
|
@ -32,6 +32,7 @@ IS_COMPONENT = 1
|
|||
REQUIRES = xpcom nkcache pref js mime dbm util jar locale intl
|
||||
|
||||
CPPSRCS = nsNetModule.cpp
|
||||
EXPORTS = nsNetCID.h
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/libneckobase_s.$(LIB_SUFFIX) \
|
||||
|
|
|
@ -28,6 +28,10 @@ DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
|||
|
||||
LCFLAGS = -DWIN32_LEAN_AND_MEAN -D_IMPL_NS_NET
|
||||
|
||||
EXPORTS = \
|
||||
nsNetCID.h \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsNetModule.obj \
|
||||
$(NULL)
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
#ifndef nsNetCID_h__
|
||||
#define nsNetCID_h__
|
||||
|
||||
//
|
||||
// nsStreamObserverProxy
|
||||
//
|
||||
#define NS_STREAMOBSERVERPROXY_CLASSNAME \
|
||||
"Stream Observer Proxy"
|
||||
#define NS_STREAMOBSERVERPROXY_CONTRACTID \
|
||||
"@mozilla.org/network/stream-observer-proxy;1"
|
||||
#define NS_STREAMOBSERVERPROXY_CID \
|
||||
{ /* 51fa28c7-74c0-4b85-9c46-d03faa7b696b */ \
|
||||
0x51fa28c7, \
|
||||
0x74c0, \
|
||||
0x4b85, \
|
||||
{0x9c, 0x46, 0xd0, 0x3f, 0xaa, 0x7b, 0x69, 0x6b} \
|
||||
}
|
||||
|
||||
//
|
||||
// nsStreamListenerProxy
|
||||
//
|
||||
#define NS_STREAMLISTENERPROXY_CLASSNAME \
|
||||
"Stream Listener Proxy"
|
||||
#define NS_STREAMLISTENERPROXY_CONTRACTID \
|
||||
"@mozilla.org/network/stream-listener-proxy;1"
|
||||
#define NS_STREAMLISTENERPROXY_CID \
|
||||
{ /* 96c48f15-aa8a-4da7-a9d5-e842bd76f015 */ \
|
||||
0x96c48f15, \
|
||||
0xaa8a, \
|
||||
0x4da7, \
|
||||
{0xa9, 0xd5, 0xe8, 0x42, 0xbd, 0x76, 0xf0, 0x15} \
|
||||
}
|
||||
|
||||
//
|
||||
// nsStreamProviderProxy
|
||||
//
|
||||
#define NS_STREAMPROVIDERPROXY_CLASSNAME \
|
||||
"Stream Provider Proxy"
|
||||
#define NS_STREAMPROVIDERPROXY_CONTRACTID \
|
||||
"@mozilla.org/network/stream-provider-proxy;1"
|
||||
#define NS_STREAMPROVIDERPROXY_CID \
|
||||
{ /* ae964fcf-9c27-40f7-9bbd-78894bfc1f31 */ \
|
||||
0xae964fcf, \
|
||||
0x9c27, \
|
||||
0x40f7, \
|
||||
{0x9b, 0xbd, 0x78, 0x89, 0x4b, 0xfc, 0x1f, 0x31} \
|
||||
}
|
||||
|
||||
//
|
||||
// nsSimpleStreamListener
|
||||
//
|
||||
#define NS_SIMPLESTREAMLISTENER_CLASSNAME \
|
||||
"Simple Stream Listener"
|
||||
#define NS_SIMPLESTREAMLISTENER_CONTRACTID \
|
||||
"@mozilla.org/network/simple-stream-listener;1"
|
||||
#define NS_SIMPLESTREAMLISTENER_CID \
|
||||
{ /* fb8cbf4e-4701-4ba1-b1d6-5388e041fb67 */ \
|
||||
0xfb8cbf4e, \
|
||||
0x4701, \
|
||||
0x4ba1, \
|
||||
{0xb1, 0xd6, 0x53, 0x88, 0xe0, 0x41, 0xfb, 0x67} \
|
||||
}
|
||||
|
||||
//
|
||||
// nsSimpleStreamProvider
|
||||
//
|
||||
#define NS_SIMPLESTREAMPROVIDER_CLASSNAME \
|
||||
"Simple Stream Provider"
|
||||
#define NS_SIMPLESTREAMPROVIDER_CONTRACTID \
|
||||
"@mozilla.org/network/simple-stream-provider;1"
|
||||
#define NS_SIMPLESTREAMPROVIDER_CID \
|
||||
{ /* f9f6a519-4efb-4f36-af40-2a5ec3992710 */ \
|
||||
0xf9f6a519, \
|
||||
0x4efb, \
|
||||
0x4f36, \
|
||||
{0xaf, 0x40, 0x2a, 0x5e, 0xc3, 0x99, 0x27, 0x10} \
|
||||
}
|
||||
|
||||
//
|
||||
// nsAsyncStreamObserver
|
||||
//
|
||||
#define NS_ASYNCSTREAMOBSERVER_CID \
|
||||
{ /* fcc7c380-91b3-11d3-8cd9-0060b0fc14a3 */ \
|
||||
0xfcc7c380, \
|
||||
0x91b3, \
|
||||
0x11d3, \
|
||||
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
|
||||
}
|
||||
|
||||
//
|
||||
// nsAsyncStreamListener
|
||||
//
|
||||
#define NS_ASYNCSTREAMLISTENER_CID \
|
||||
{ /* 60047bb2-91c0-11d3-8cd9-0060b0fc14a3 */ \
|
||||
0x60047bb2, \
|
||||
0x91c0, \
|
||||
0x11d3, \
|
||||
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
|
||||
}
|
||||
|
||||
|
||||
#endif /* !nsNetCID_h__ */
|
|
@ -42,12 +42,14 @@
|
|||
#include "nsStreamLoader.h"
|
||||
#include "nsDownloader.h"
|
||||
#include "nsAsyncStreamListener.h"
|
||||
#include "nsSyncStreamListener.h"
|
||||
//#include "nsSyncStreamListener.h"
|
||||
#include "nsFileStreams.h"
|
||||
#include "nsBufferedStreams.h"
|
||||
#include "nsProtocolProxyService.h"
|
||||
#include "nsSOCKSSocketProvider.h"
|
||||
|
||||
#include "nsNetCID.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "nsStreamConverterService.h"
|
||||
|
@ -74,7 +76,21 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCacheManager, Init)
|
|||
#include "nsXMLMIMEDataSource.h"
|
||||
#include "nsMIMEInfoImpl.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMIMEInfoImpl);
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMIMEInfoImpl)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "nsStreamObserverProxy.h"
|
||||
#include "nsStreamListenerProxy.h"
|
||||
#include "nsStreamProviderProxy.h"
|
||||
#include "nsSimpleStreamListener.h"
|
||||
#include "nsSimpleStreamProvider.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStreamObserverProxy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStreamListenerProxy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsStreamProviderProxy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSimpleStreamListener)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSimpleStreamProvider)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -400,6 +416,26 @@ static nsModuleComponentInfo gNetModuleInfo[] = {
|
|||
NS_DOWNLOADER_CID,
|
||||
"@mozilla.org/network/downloader;1",
|
||||
nsDownloader::Create },
|
||||
{ NS_STREAMOBSERVERPROXY_CLASSNAME,
|
||||
NS_STREAMOBSERVERPROXY_CID,
|
||||
NS_STREAMOBSERVERPROXY_CONTRACTID,
|
||||
nsStreamObserverProxyConstructor },
|
||||
{ NS_STREAMLISTENERPROXY_CLASSNAME,
|
||||
NS_STREAMLISTENERPROXY_CID,
|
||||
NS_STREAMLISTENERPROXY_CONTRACTID,
|
||||
nsStreamListenerProxyConstructor },
|
||||
{ NS_STREAMPROVIDERPROXY_CLASSNAME,
|
||||
NS_STREAMPROVIDERPROXY_CID,
|
||||
NS_STREAMPROVIDERPROXY_CONTRACTID,
|
||||
nsStreamProviderProxyConstructor },
|
||||
{ NS_SIMPLESTREAMLISTENER_CLASSNAME,
|
||||
NS_SIMPLESTREAMLISTENER_CID,
|
||||
NS_SIMPLESTREAMLISTENER_CONTRACTID,
|
||||
nsSimpleStreamListenerConstructor },
|
||||
{ NS_SIMPLESTREAMPROVIDER_CLASSNAME,
|
||||
NS_SIMPLESTREAMPROVIDER_CID,
|
||||
NS_SIMPLESTREAMPROVIDER_CONTRACTID,
|
||||
nsSimpleStreamProviderConstructor },
|
||||
{ "Async Stream Observer",
|
||||
NS_ASYNCSTREAMOBSERVER_CID,
|
||||
"@mozilla.org/network/async-stream-observer;1",
|
||||
|
@ -408,10 +444,12 @@ static nsModuleComponentInfo gNetModuleInfo[] = {
|
|||
NS_ASYNCSTREAMLISTENER_CID,
|
||||
"@mozilla.org/network/async-stream-listener;1",
|
||||
nsAsyncStreamListener::Create },
|
||||
/*
|
||||
{ "Sync Stream Listener",
|
||||
NS_SYNCSTREAMLISTENER_CID,
|
||||
"@mozilla.org/network/sync-stream-listener;1",
|
||||
nsSyncStreamListener::Create },
|
||||
*/
|
||||
{ "Load Group",
|
||||
NS_LOADGROUP_CID,
|
||||
"@mozilla.org/network/load-group;1",
|
||||
|
|
|
@ -434,8 +434,7 @@ nsDiskCacheRecordChannel::AsyncRead(nsIStreamListener *aListener,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDiskCacheRecordChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsDiskCacheRecordChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
|
||||
{
|
||||
|
|
|
@ -525,14 +525,15 @@ nsMemCacheChannel::AsyncRead(nsIStreamListener *aListener, nsISupports *aContext
|
|||
mAsyncReadStream = asyncReadStreamAdaptor;
|
||||
|
||||
rv = asyncReadStreamAdaptor->AsyncRead(aListener, aContext);
|
||||
if (NS_FAILED(rv))
|
||||
delete asyncReadStreamAdaptor;
|
||||
if (NS_FAILED(rv)) {
|
||||
mAsyncReadStream = nsnull;
|
||||
NS_RELEASE(asyncReadStreamAdaptor);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMemCacheChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer, nsISupports *ctxt)
|
||||
nsMemCacheChannel::AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt)
|
||||
{
|
||||
// Not required to be implemented
|
||||
NS_NOTREACHED("nsMemCacheChannel::AsyncWrite");
|
||||
|
|
|
@ -203,8 +203,7 @@ nsCacheEntryChannel::AsyncRead(nsIStreamListener *aListener, nsISupports *aConte
|
|||
|
||||
// No async writes allowed to the cache yet
|
||||
NS_IMETHODIMP
|
||||
nsCacheEntryChannel::AsyncWrite(nsIInputStream *aFromStream,
|
||||
nsIStreamObserver *aObserver,
|
||||
nsCacheEntryChannel::AsyncWrite(nsIStreamProvider *aProvider,
|
||||
nsISupports *aContext)
|
||||
{
|
||||
NS_NOTREACHED("nsCacheEntryChannel::AsyncWrite");
|
||||
|
|
|
@ -59,8 +59,7 @@ public:
|
|||
NS_IMETHOD OpenOutputStream(nsIOutputStream* *aOutputStream);
|
||||
NS_IMETHOD OpenInputStream(nsIInputStream* *aInputStream);
|
||||
NS_IMETHOD AsyncRead(nsIStreamListener *aListener, nsISupports *aContext);
|
||||
NS_IMETHOD AsyncWrite(nsIInputStream *aFromStream,
|
||||
nsIStreamObserver *aObserver, nsISupports *aContext);
|
||||
NS_IMETHOD AsyncWrite(nsIStreamProvider *aProvider, nsISupports *aContext);
|
||||
NS_IMETHOD GetLoadAttributes(nsLoadFlags *aLoadAttributes);
|
||||
NS_IMETHOD SetLoadAttributes(nsLoadFlags aLoadAttributes);
|
||||
NS_IMETHOD GetLoadGroup(nsILoadGroup* *aLoadGroup);
|
||||
|
|
|
@ -357,8 +357,7 @@ nsDataChannel::AsyncRead(nsIStreamListener *aListener, nsISupports *ctxt)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDataChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsDataChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
// you can't write to a data url
|
||||
|
|
|
@ -202,8 +202,7 @@ nsDateTimeChannel::AsyncRead(nsIStreamListener *aListener,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDateTimeChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsDateTimeChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("nsDateTimeChannel::AsyncWrite");
|
||||
|
|
|
@ -353,8 +353,7 @@ nsFileChannel::AsyncRead(nsIStreamListener *listener,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFileChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsFileChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -392,7 +391,7 @@ nsFileChannel::AsyncWrite(nsIInputStream *fromStream,
|
|||
rv = EnsureTransport();
|
||||
if (NS_FAILED(rv)) goto done;
|
||||
|
||||
rv = mFileTransport->AsyncWrite(fromStream, observer, ctxt);
|
||||
rv = mFileTransport->AsyncWrite(provider, ctxt);
|
||||
|
||||
done:
|
||||
if (NS_FAILED(rv)) {
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "nsMimeTypes.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsITXTToHTMLConv.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
||||
static NS_DEFINE_CID(kStreamConverterServiceCID, NS_STREAMCONVERTERSERVICE_CID);
|
||||
|
@ -250,8 +251,7 @@ nsFingerChannel::AsyncRead(nsIStreamListener *aListener, nsISupports *ctxt)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFingerChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsFingerChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("nsFingerChannel::AsyncWrite");
|
||||
|
@ -540,7 +540,7 @@ nsFingerChannel::SendRequest(nsIChannel* aChannel) {
|
|||
|
||||
rv = aChannel->SetTransferCount(requestBuffer.Length());
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = aChannel->AsyncWrite(charstream, this, 0);
|
||||
rv = NS_AsyncWriteFromStream(aChannel, charstream, this, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -293,13 +293,12 @@ nsFTPChannel::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFTPChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsFTPChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
mObserver = observer;
|
||||
mObserver = provider;
|
||||
mUserContext = ctxt;
|
||||
|
||||
if (mProxyChannel) {
|
||||
|
@ -307,9 +306,11 @@ nsFTPChannel::AsyncWrite(nsIInputStream *fromStream,
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
rv = mProxyChannel->SetTransferCount(mAmount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return mProxyChannel->AsyncWrite(fromStream, observer, ctxt);
|
||||
return mProxyChannel->AsyncWrite(provider, ctxt);
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#if 0
|
||||
NS_ASSERTION(mAmount > 0, "FTP requires stream len info");
|
||||
if (mAmount < 1) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
|
@ -334,6 +335,7 @@ nsFTPChannel::AsyncWrite(nsIInputStream *fromStream,
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return mFTPState->Connect();
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -1328,7 +1328,7 @@ nsFtpState::S_stor() {
|
|||
mFireCallbacks = PR_FALSE; // observer callbacks will be handled by the transport.
|
||||
|
||||
PR_LOG(gFTPLog, PR_LOG_DEBUG, ("(%x) writing on Data Transport\n", this));
|
||||
return mDPipe->AsyncWrite(mWriteStream, mObserver, mObserverContext);
|
||||
return NS_AsyncWriteFromStream(mDPipe, mWriteStream, mObserver, mObserverContext);
|
||||
}
|
||||
|
||||
FTP_STATE
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "prlog.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
extern PRLogModuleInfo* gFTPLog;
|
||||
|
@ -102,7 +103,7 @@ nsFtpControlConnection::Connect()
|
|||
// to indicate between the read and the write transport. We will be passing the a non-null
|
||||
// context for the write, and a null context for the read.
|
||||
|
||||
rv = mCPipe->AsyncWrite(inStream, NS_STATIC_CAST(nsIStreamObserver*, this), NS_STATIC_CAST(nsISupports*, this));
|
||||
rv = NS_AsyncWriteFromStream(mCPipe, inStream, NS_STATIC_CAST(nsIStreamObserver*, this), NS_STATIC_CAST(nsISupports*, this));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// get the ball rolling by reading on the control socket.
|
||||
|
|
|
@ -344,10 +344,12 @@ nsHTTPChannel::AsyncRead(nsIStreamListener *listener, nsISupports *aContext)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTTPChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsHTTPChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("nsHTTPChannel::AsyncWrite");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#if 0
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// parameter validation
|
||||
|
@ -365,6 +367,7 @@ nsHTTPChannel::AsyncWrite(nsIInputStream *fromStream,
|
|||
Open();
|
||||
|
||||
return rv;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsISocketTransport.h"
|
||||
#include "nsISSLSocketControl.h"
|
||||
#include "plstr.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
extern PRLogModuleInfo* gHTTPLog;
|
||||
|
@ -732,7 +733,7 @@ nsHTTPPipelinedRequest::WriteRequest(nsIInputStream* iRequestStream)
|
|||
}
|
||||
|
||||
mOnStopDone = PR_FALSE;
|
||||
rv = mTransport->AsyncWrite(stream, this,(nsISupports*)(nsIRequest*)req->mConnection);
|
||||
rv = NS_AsyncWriteFromStream(mTransport, stream, this, (nsISupports*)(nsIRequest*)req->mConnection);
|
||||
NS_RELEASE(req);
|
||||
|
||||
return rv;
|
||||
|
@ -782,7 +783,7 @@ nsHTTPPipelinedRequest::OnStopRequest(nsIChannel* channel, nsISupports* i_Contex
|
|||
("nsHTTPRequest [this=%x]. "
|
||||
"Writing PUT/POST data to the server.\n", this));
|
||||
|
||||
rv = mTransport->AsyncWrite(mInputStream, this,
|
||||
rv = NS_AsyncWriteFromStream(mTransport, mInputStream, this,
|
||||
(nsISupports*)(nsIRequest*)req->mConnection);
|
||||
|
||||
/* the mInputStream is released below... */
|
||||
|
|
|
@ -648,7 +648,8 @@ nsHTTPServerListener::OnStartRequest(nsIChannel* channel, nsISupports* i_pContex
|
|||
mChunkHeaderCtx.SetEOF(PR_FALSE) ;
|
||||
|
||||
nsHTTPRequest * req;
|
||||
mPipelinedRequest->GetCurrentRequest(&req) ;
|
||||
if (mPipelinedRequest)
|
||||
mPipelinedRequest->GetCurrentRequest(&req) ;
|
||||
|
||||
if (req)
|
||||
{
|
||||
|
@ -851,6 +852,14 @@ nsresult nsHTTPServerListener::FireSingleOnData(nsIStreamListener *aListener,
|
|||
return rv;
|
||||
}
|
||||
|
||||
struct nsWriteLineInfo
|
||||
{
|
||||
nsCString &buf;
|
||||
PRBool haveLF;
|
||||
|
||||
nsWriteLineInfo(nsCString &b) : buf(b), haveLF(0) {}
|
||||
};
|
||||
|
||||
static NS_METHOD
|
||||
nsWriteLineToString(nsIInputStream* in,
|
||||
void* closure,
|
||||
|
@ -859,29 +868,29 @@ nsWriteLineToString(nsIInputStream* in,
|
|||
PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
nsCString* str = (nsCString*)closure;
|
||||
nsWriteLineInfo *info = (nsWriteLineInfo *) closure;
|
||||
*writeCount = 0;
|
||||
|
||||
if (info->haveLF)
|
||||
// Stop reading
|
||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||
else
|
||||
{
|
||||
char c = 0;
|
||||
|
||||
const char *buf = fromRawSegment;
|
||||
const char *p = fromRawSegment;
|
||||
for (; count>0; --count) {
|
||||
c = *buf++;
|
||||
c = *p++;
|
||||
(*writeCount)++;
|
||||
if (c == LF) {
|
||||
info->haveLF = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
str->Append(fromRawSegment, *writeCount);
|
||||
//
|
||||
// If the entire segment has been read, and no LF has been found,
|
||||
// then return OK to continue reading the next segment (if there
|
||||
// is one). Else, return WOULD_BLOCK to cause ReadSegments to exit
|
||||
// and allow us to parse this header.
|
||||
//
|
||||
return (c != LF) ? NS_OK : NS_BASE_STREAM_WOULD_BLOCK;
|
||||
info->buf.Append(fromRawSegment, *writeCount);
|
||||
// Successfully read something
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsresult nsHTTPServerListener::ParseStatusLine(nsIInputStream* in,
|
||||
PRUint32 aLength,
|
||||
|
@ -901,8 +910,9 @@ nsresult nsHTTPServerListener::ParseStatusLine(nsIInputStream* in,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsWriteLineInfo info(mHeaderBuffer);
|
||||
rv = in->ReadSegments(nsWriteLineToString,
|
||||
(void*) &mHeaderBuffer,
|
||||
(void*) &info,
|
||||
aLength,
|
||||
&actualBytesRead) ;
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -987,8 +997,9 @@ nsresult nsHTTPServerListener::ParseHTTPHeader(nsIInputStream* in,
|
|||
PRInt32 newlineOffset = 0;
|
||||
do {
|
||||
// Append the buffer into the header string...
|
||||
nsWriteLineInfo info(mHeaderBuffer);
|
||||
rv = in->ReadSegments(nsWriteLineToString,
|
||||
(void*) &mHeaderBuffer,
|
||||
(void*) &info,
|
||||
totalBytesToRead,
|
||||
&actualBytesRead);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
|
|
@ -392,8 +392,7 @@ nsJARChannel::AsyncReadJARElement()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::AsyncWrite(nsIInputStream* fromStream,
|
||||
nsIStreamObserver* observer,
|
||||
nsJARChannel::AsyncWrite(nsIStreamProvider* provider,
|
||||
nsISupports* ctxt)
|
||||
{
|
||||
NS_NOTREACHED("nsJARChannel::AsyncWrite");
|
||||
|
|
|
@ -92,7 +92,7 @@ NS_IMPL_ISUPPORTS5(nsResChannel,
|
|||
nsIChannel,
|
||||
nsIRequest,
|
||||
nsIStreamListener,
|
||||
nsIStreamObserver)
|
||||
nsIStreamProvider)
|
||||
|
||||
NS_METHOD
|
||||
nsResChannel::Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult)
|
||||
|
@ -428,8 +428,7 @@ nsResChannel::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsResChannel::AsyncWrite(nsIInputStream *fromStream,
|
||||
nsIStreamObserver *observer,
|
||||
nsResChannel::AsyncWrite(nsIStreamProvider *provider,
|
||||
nsISupports *ctxt)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -459,16 +458,15 @@ nsResChannel::AsyncWrite(nsIInputStream *fromStream,
|
|||
}
|
||||
NS_ASSERTION(mState == ASYNC_READ, "wrong state");
|
||||
|
||||
mFromStream = fromStream;
|
||||
mUserContext = ctxt;
|
||||
mUserObserver = observer;
|
||||
mUserObserver = provider;
|
||||
|
||||
do {
|
||||
rv = EnsureNextResolvedChannel();
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
if (mResolvedChannel)
|
||||
rv = mResolvedChannel->AsyncWrite(fromStream, this, nsnull);
|
||||
rv = mResolvedChannel->AsyncWrite(this, nsnull);
|
||||
// Later, this AsyncWrite will call back our OnStopRequest
|
||||
// method. The action resumes there...
|
||||
} while (NS_FAILED(rv));
|
||||
|
@ -704,7 +702,7 @@ nsResChannel::OnStopRequest(nsIChannel* transportChannel, nsISupports* context,
|
|||
case ASYNC_READ:
|
||||
return AsyncRead(GetUserListener(), mUserContext);
|
||||
case ASYNC_WRITE:
|
||||
return AsyncWrite(mFromStream, mUserObserver, mUserContext);
|
||||
return AsyncWrite(GetUserProvider(), mUserContext);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -725,10 +723,9 @@ nsResChannel::EndRequest(nsresult aStatus, const PRUnichar* aStatusArg)
|
|||
}
|
||||
#endif
|
||||
// Release the reference to the consumer stream listener...
|
||||
mUserObserver = null_nsCOMPtr();
|
||||
mUserContext = null_nsCOMPtr();
|
||||
mResolvedChannel = null_nsCOMPtr();
|
||||
mFromStream = null_nsCOMPtr();
|
||||
mUserObserver = 0;
|
||||
mUserContext = 0;
|
||||
mResolvedChannel = 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -745,4 +742,16 @@ nsResChannel::OnDataAvailable(nsIChannel* transportChannel, nsISupports* context
|
|||
aSourceOffset, aLength);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsResChannel::OnDataWritable(nsIChannel* transportChannel, nsISupports* context,
|
||||
nsIOutputStream *aOStream, PRUint32 aOffset, PRUint32 aLength)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
NS_ASSERTION(mInitiator == PR_CurrentThread(),
|
||||
"wrong thread calling this routine");
|
||||
#endif
|
||||
return GetUserProvider()->OnDataWritable(this, mUserContext, aOStream,
|
||||
aOffset, aLength);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "nsIResChannel.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsIResProtocolHandler.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
|
@ -38,7 +39,8 @@
|
|||
#endif
|
||||
|
||||
class nsResChannel : public nsIResChannel,
|
||||
public nsIStreamListener
|
||||
public nsIStreamListener,
|
||||
public nsIStreamProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -47,6 +49,7 @@ public:
|
|||
NS_DECL_NSIRESCHANNEL
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSISTREAMPROVIDER
|
||||
|
||||
nsResChannel();
|
||||
virtual ~nsResChannel();
|
||||
|
@ -90,6 +93,15 @@ protected:
|
|||
return listener;
|
||||
}
|
||||
|
||||
nsIStreamProvider* GetUserProvider() {
|
||||
// this method doesn't addref the provider
|
||||
NS_ASSERTION(mState == ASYNC_WRITE, "wrong state");
|
||||
// this cast is safe because we set mUserObserver in AsyncWrite
|
||||
nsIStreamObserver* obs = mUserObserver;
|
||||
nsIStreamProvider* provider = NS_STATIC_CAST(nsIStreamProvider*, obs);
|
||||
return provider;
|
||||
}
|
||||
|
||||
nsresult EnsureNextResolvedChannel();
|
||||
nsresult EndRequest(nsresult aStatus, const PRUnichar* aStatusArg);
|
||||
|
||||
|
@ -107,7 +119,6 @@ protected:
|
|||
Substitutions mSubstitutions;
|
||||
nsCOMPtr<nsIStreamObserver> mUserObserver;
|
||||
nsCOMPtr<nsISupports> mUserContext;
|
||||
nsCOMPtr<nsIInputStream> mFromStream;
|
||||
PRUint32 mStartPosition;
|
||||
PRInt32 mCount;
|
||||
PRUint32 mBufferSegmentSize;
|
||||
|
|
|
@ -29,6 +29,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
MODULE = test_necko
|
||||
REQUIRES = xpcom necko timer cookie layout widget dom
|
||||
|
||||
SHARED_LIBRARY_LIBS = $(DIST)/lib/libmozdbm_s.$(LIB_SUFFIX)
|
||||
|
||||
CPPSRCS = \
|
||||
TestSocketIO.cpp \
|
||||
TestSocketInput.cpp \
|
||||
|
@ -37,9 +39,11 @@ CPPSRCS = \
|
|||
TestProtocols.cpp \
|
||||
urltest.cpp \
|
||||
TestFileInput2.cpp \
|
||||
TestFileTransport.cpp \
|
||||
TestRes.cpp \
|
||||
TestCallbacks.cpp \
|
||||
TestSyncHTTP.cpp \
|
||||
TestDBMAccess.cpp \
|
||||
$(NULL)
|
||||
|
||||
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
|
||||
|
@ -59,6 +63,7 @@ LIBS = \
|
|||
$(XPCOM_LIBS) \
|
||||
$(LOST_SYM_LIBS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(SHARED_LIBRARY_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -31,6 +31,19 @@
|
|||
#include "nsIStreamListener.h"
|
||||
#include "nsIEventQueueService.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "prlog.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
static PRLogModuleInfo *gTestFileTransportLog = nsnull;
|
||||
#define PRINTF(args) PR_LOG(gTestFileTransportLog, PR_LOG_ALWAYS, args)
|
||||
#else
|
||||
#define PRINTF(args)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
@ -46,13 +59,13 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
|
||||
NS_IMETHOD OnStartRequest(nsIChannel *channel, nsISupports *ctxt) {
|
||||
printf("starting\n");
|
||||
PRINTF(("starting\n"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD OnStopRequest(nsIChannel *channel, nsISupports *ctxt,
|
||||
nsresult aStatus, const PRUnichar* aStatusArg) {
|
||||
printf("ending status=%0x total=%d\n", aStatus, mTotal);
|
||||
PRINTF(("ending status=%0x total=%d\n", aStatus, mTotal));
|
||||
if (--mStopCount == 0)
|
||||
gDone = PR_TRUE;
|
||||
return NS_OK;
|
||||
|
@ -61,9 +74,9 @@ public:
|
|||
NS_IMETHOD OnDataAvailable(nsIChannel *channel, nsISupports *ctxt,
|
||||
nsIInputStream *inStr, PRUint32 sourceOffset,
|
||||
PRUint32 count) {
|
||||
printf("receiving %d bytes\n", count);
|
||||
PRINTF(("receiving %d bytes\n", count));
|
||||
char buf[256];
|
||||
PRUint32 writeCount;
|
||||
PRUint32 writeCount, givenCount=count;
|
||||
nsresult rv;
|
||||
while (count > 0) {
|
||||
PRUint32 amt = PR_MIN(count, 256);
|
||||
|
@ -71,12 +84,15 @@ public:
|
|||
rv = inStr->Read(buf, amt, &readCount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ASSERTION(readCount != 0, "premature EOF");
|
||||
nsresult rv = mOut->Write(buf, readCount, &writeCount);
|
||||
rv = mOut->Write(buf, readCount, &writeCount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ASSERTION(writeCount == readCount, "failed to write all the data");
|
||||
count -= readCount;
|
||||
mTotal += readCount;
|
||||
}
|
||||
PRINTF(("done reading data [read %u bytes]\n", givenCount - count));
|
||||
//PRINTF("sleeping for 100 ticks\n");FLUSH();
|
||||
//PR_Sleep(100);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -124,6 +140,8 @@ TestAsyncRead(const char* fileName, PRUint32 offset, PRInt32 length)
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
PRINTF(("TestAsyncRead\n"));
|
||||
|
||||
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -151,7 +169,7 @@ TestAsyncRead(const char* fileName, PRUint32 offset, PRInt32 length)
|
|||
|
||||
while (!gDone) {
|
||||
PLEvent* event;
|
||||
rv = gEventQ->GetEvent(&event);
|
||||
rv = gEventQ->WaitForEvent(&event);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = gEventQ->HandleEvent(event);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -169,6 +187,8 @@ TestAsyncWrite(const char* fileName, PRUint32 offset, PRInt32 length)
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
PRINTF(("TestAsyncWrite\n"));
|
||||
|
||||
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
@ -202,12 +222,12 @@ TestAsyncWrite(const char* fileName, PRUint32 offset, PRInt32 length)
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
rv = fileTrans->SetTransferCount(length);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = fileTrans->AsyncWrite(inStr, listener, nsnull);
|
||||
rv = NS_AsyncWriteFromStream(fileTrans, inStr, listener, nsnull);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
while (!gDone) {
|
||||
PLEvent* event;
|
||||
rv = gEventQ->GetEvent(&event);
|
||||
rv = gEventQ->WaitForEvent(&event);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = gEventQ->HandleEvent(event);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -233,15 +253,15 @@ public:
|
|||
PRInt32 length;
|
||||
rv = channel->GetContentLength(&length);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
printf("stream opened: content type = %s, length = %d\n",
|
||||
contentType, length);
|
||||
PRINTF(("stream opened: content type = %s, length = %d\n",
|
||||
contentType, length));
|
||||
nsCRT::free(contentType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHOD OnStopRequest(nsIChannel *channel, nsISupports *ctxt,
|
||||
nsresult aStatus, const PRUnichar* aStatusArg) {
|
||||
printf("stream closed: status %x\n", aStatus);
|
||||
PRINTF(("stream closed: status %x\n", aStatus));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -265,6 +285,10 @@ main(int argc, char* argv[])
|
|||
{
|
||||
nsresult rv;
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
gTestFileTransportLog = PR_NewLogModule("TestFileTransport");
|
||||
#endif
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: %s <file-to-read>\n", argv[0]);
|
||||
return -1;
|
||||
|
|
|
@ -651,7 +651,7 @@ main(int argc, char* argv[])
|
|||
/* Mac stuff is missing here! */
|
||||
#else
|
||||
PLEvent *gEvent;
|
||||
rv = gEventQ->GetEvent(&gEvent);
|
||||
rv = gEventQ->WaitForEvent(&gEvent);
|
||||
rv = gEventQ->HandleEvent(gEvent);
|
||||
#endif /* XP_UNIX */
|
||||
#endif /* !WIN32 */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
* Contributor(s):
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
|
@ -34,13 +35,19 @@
|
|||
#include "nsIEventQueueService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIStreamObserver.h"
|
||||
#include "nsIStreamProvider.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIByteArrayInputStream.h"
|
||||
|
||||
#if defined(PR_LOGGING)
|
||||
static PRLogModuleInfo *gTestSocketIOLog;
|
||||
#endif
|
||||
#define LOG(args) PR_LOG(gTestSocketIOLog, PR_LOG_DEBUG, args)
|
||||
|
||||
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
|
||||
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
||||
|
@ -50,250 +57,310 @@ static PRTime gElapsedTime;
|
|||
static int gKeepRunning = 1;
|
||||
static nsIEventQueue* gEventQ = nsnull;
|
||||
|
||||
class InputTestConsumer : public nsIStreamListener
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Test Listener
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
class TestListener : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
|
||||
InputTestConsumer();
|
||||
virtual ~InputTestConsumer();
|
||||
TestListener() { NS_INIT_ISUPPORTS(); }
|
||||
virtual ~TestListener() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
};
|
||||
|
||||
|
||||
InputTestConsumer::InputTestConsumer()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
InputTestConsumer::~InputTestConsumer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(InputTestConsumer);
|
||||
NS_IMPL_RELEASE(InputTestConsumer);
|
||||
NS_IMPL_QUERY_INTERFACE2(InputTestConsumer,
|
||||
NS_IMPL_ISUPPORTS2(TestListener,
|
||||
nsIStreamObserver,
|
||||
nsIStreamListener);
|
||||
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
InputTestConsumer::OnStartRequest(nsIChannel* channel, nsISupports* context)
|
||||
TestListener::OnStartRequest(nsIChannel* channel, nsISupports* context)
|
||||
{
|
||||
printf("\n+++ InputTestConsumer::OnStartRequest +++\n");
|
||||
LOG(("TestListener::OnStartRequest\n"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
InputTestConsumer::OnDataAvailable(nsIChannel* channel,
|
||||
TestListener::OnDataAvailable(nsIChannel* channel,
|
||||
nsISupports* context,
|
||||
nsIInputStream *aIStream,
|
||||
PRUint32 aSourceOffset,
|
||||
PRUint32 aLength)
|
||||
{
|
||||
LOG(("TestListener::OnDataAvailable [offset=%u length=%u]\n",
|
||||
aSourceOffset, aLength));
|
||||
char buf[1025];
|
||||
PRUint32 amt;
|
||||
do {
|
||||
while (1) {
|
||||
aIStream->Read(buf, 1024, &amt);
|
||||
if (amt == 0) break;
|
||||
if (amt == 0)
|
||||
break;
|
||||
buf[amt] = '\0';
|
||||
puts(buf);
|
||||
} while (amt != 0);
|
||||
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
InputTestConsumer::OnStopRequest(nsIChannel* channel, nsISupports* context,
|
||||
TestListener::OnStopRequest(nsIChannel* channel, nsISupports* context,
|
||||
nsresult aStatus, const PRUnichar* aStatusArg)
|
||||
{
|
||||
LOG(("TestListener::OnStopRequest [aStatus=%x]\n", aStatus));
|
||||
gKeepRunning = 0;
|
||||
printf("\n+++ InputTestConsumer::OnStopRequest (status = %x) +++\n", aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Test Provider
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
|
||||
class TestWriteObserver : public nsIStreamObserver
|
||||
class TestProvider : public nsIStreamProvider
|
||||
{
|
||||
public:
|
||||
|
||||
TestWriteObserver(nsIChannel* aChannel);
|
||||
virtual ~TestWriteObserver();
|
||||
TestProvider(char *data);
|
||||
virtual ~TestProvider();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISTREAMOBSERVER
|
||||
NS_DECL_NSISTREAMPROVIDER
|
||||
|
||||
protected:
|
||||
nsIChannel* mTransport;
|
||||
nsCOMPtr<nsIByteArrayInputStream> mData;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS2(TestProvider,
|
||||
nsIStreamProvider,
|
||||
nsIStreamObserver)
|
||||
|
||||
TestWriteObserver::TestWriteObserver(nsIChannel* aChannel)
|
||||
TestProvider::TestProvider(char *data)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
mTransport = aChannel;
|
||||
NS_ADDREF(mTransport);
|
||||
NS_INIT_ISUPPORTS();
|
||||
NS_NewByteArrayInputStream(getter_AddRefs(mData), data, strlen(data));
|
||||
LOG(("Constructing TestProvider [this=%x]\n", this));
|
||||
}
|
||||
|
||||
TestWriteObserver::~TestWriteObserver()
|
||||
TestProvider::~TestProvider()
|
||||
{
|
||||
NS_RELEASE(mTransport);
|
||||
LOG(("Destroying TestProvider [this=%x]\n", this));
|
||||
}
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(TestWriteObserver,NS_GET_IID(nsIStreamObserver));
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
TestWriteObserver::OnStartRequest(nsIChannel* channel, nsISupports* context)
|
||||
TestProvider::OnStartRequest(nsIChannel* channel, nsISupports* context)
|
||||
{
|
||||
printf("\n+++ TestWriteObserver::OnStartRequest +++\n");
|
||||
LOG(("TestProvider::OnStartRequest [this=%x]\n", this));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
TestWriteObserver::OnStopRequest(nsIChannel* channel, nsISupports* context,
|
||||
TestProvider::OnStopRequest(nsIChannel* channel, nsISupports* context,
|
||||
nsresult aStatus, const PRUnichar* aStatusArg)
|
||||
{
|
||||
printf("\n+++ TestWriteObserver::OnStopRequest (status = %x) +++\n", aStatus);
|
||||
LOG(("TestProvider::OnStopRequest [status=%x]\n", aStatus));
|
||||
|
||||
if (NS_SUCCEEDED(aStatus)) {
|
||||
mTransport->AsyncRead(nsnull, new InputTestConsumer);
|
||||
} else {
|
||||
nsCOMPtr<nsIStreamListener> listener = do_QueryInterface(new TestListener());
|
||||
|
||||
if (NS_SUCCEEDED(aStatus))
|
||||
channel->AsyncRead(listener, nsnull);
|
||||
else
|
||||
gKeepRunning = 0;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult NS_AutoregisterComponents()
|
||||
NS_IMETHODIMP
|
||||
TestProvider::OnDataWritable(nsIChannel *channel, nsISupports *context,
|
||||
nsIOutputStream *output, PRUint32 offset, PRUint32 count)
|
||||
{
|
||||
nsresult rv = nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup, NULL /* default */);
|
||||
LOG(("TestProvider::OnDataWritable [offset=%u, count=%u]\n", offset, count));
|
||||
PRUint32 writeCount;
|
||||
nsresult rv = output->WriteFrom(mData, count, &writeCount);
|
||||
// Zero bytes written on success indicates EOF
|
||||
if (NS_SUCCEEDED(rv) && (writeCount == 0))
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
return rv;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Synchronous IO
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
nsresult
|
||||
WriteRequest(nsIOutputStream *os, const char *request)
|
||||
{
|
||||
PRUint32 n;
|
||||
return os->Write(request, strlen(request), &n);
|
||||
}
|
||||
|
||||
nsresult
|
||||
ReadResponse(nsIInputStream *is)
|
||||
{
|
||||
PRUint32 bytesRead;
|
||||
char buf[2048];
|
||||
do {
|
||||
is->Read(buf, sizeof(buf), &bytesRead);
|
||||
if (bytesRead > 0)
|
||||
fwrite(buf, 1, bytesRead, stdout);
|
||||
} while (bytesRead > 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// Startup...
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
void
|
||||
sighandler(int sig)
|
||||
{
|
||||
LOG(("got signal: %d\n", sig));
|
||||
NS_BREAK();
|
||||
}
|
||||
|
||||
void
|
||||
usage(char **argv)
|
||||
{
|
||||
printf("usage: %s [-sync] <host> <path>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("usage: %s <host> <path>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
signal(SIGSEGV, sighandler);
|
||||
|
||||
char* hostName = argv[1];
|
||||
char* fileName = argv[2];
|
||||
int port = 80;
|
||||
gTestSocketIOLog = PR_NewLogModule("TestSocketIO");
|
||||
|
||||
rv = NS_AutoregisterComponents();
|
||||
if (argc < 3)
|
||||
usage(argv);
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
PRIntn i=0;
|
||||
PRBool sync = PR_FALSE;
|
||||
if (nsCRT::strcasecmp(argv[1], "-sync") == 0) {
|
||||
if (argc < 4)
|
||||
usage(argv);
|
||||
sync = PR_TRUE;
|
||||
i = 1;
|
||||
}
|
||||
|
||||
char *hostName = argv[1+i];
|
||||
char *fileName = argv[2+i];
|
||||
int port = 80;
|
||||
|
||||
// Create the Event Queue for this thread...
|
||||
NS_WITH_SERVICE(nsIEventQueueService, eventQService, kEventQueueServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to create: event queue service!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = eventQService->CreateThreadEventQueue();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = eventQService->CreateMonitoredThreadEventQueue();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to create: thread event queue!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &gEventQ);
|
||||
|
||||
// Create the Socket transport service...
|
||||
NS_WITH_SERVICE(nsISocketTransportService, sts, kSocketTransportServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// Create a stream for the data being written to the server...
|
||||
nsIInputStream* stream;
|
||||
PRUint32 bytesWritten;
|
||||
|
||||
nsCOMPtr<nsIOutputStream> out;
|
||||
rv = NS_NewPipe(&stream, getter_AddRefs(out), 1024, 4096);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
char *buffer = PR_smprintf("GET %s HTML/1.0%s%s", fileName, CRLF, CRLF);
|
||||
out->Write(buffer, strlen(buffer), &bytesWritten);
|
||||
printf("\n+++ Request is: %s\n", buffer);
|
||||
|
||||
// Create the socket transport...
|
||||
nsIChannel* transport;
|
||||
rv = sts->CreateTransport(hostName, port, nsnull, -1, 0, 0, &transport);
|
||||
|
||||
// This stuff is used to test the output stream
|
||||
#if 0
|
||||
nsIOutputStream* outStr = nsnull;
|
||||
rv = transport->OpenOutputStream(&outStr);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRUint32 bytes;
|
||||
rv = outStr->Write("test", 4, &bytes);
|
||||
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
rv = outStr->Close();
|
||||
#else
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
TestWriteObserver* observer = new TestWriteObserver(transport);
|
||||
|
||||
gElapsedTime = PR_Now();
|
||||
rv = transport->SetTransferCount(bytesWritten);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = transport->AsyncWrite(stream, nsnull, observer);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to create: socket transport service!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_RELEASE(transport);
|
||||
}
|
||||
#endif
|
||||
char *buffer = PR_smprintf("GET %s HTTP/1.1" CRLF
|
||||
"host: %s" CRLF
|
||||
"user-agent: Mozilla/5.0 (X11; N; Linux 2.2.16-22smp i686; en-US; m18) Gecko/20001220" CRLF
|
||||
"accept: */*" CRLF
|
||||
"accept-language: en" CRLF
|
||||
"accept-encoding: gzip,deflate,compress,identity" CRLF
|
||||
"keep-alive: 300" CRLF
|
||||
"connection: keep-alive" CRLF
|
||||
CRLF,
|
||||
fileName, hostName);
|
||||
LOG(("Request [\n%s]\n", buffer));
|
||||
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
// Create the socket transport...
|
||||
nsCOMPtr<nsIChannel> transport;
|
||||
rv = sts->CreateTransport(hostName, port, nsnull, -1, 0, 0, getter_AddRefs(transport));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed to create: socket transport!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
gElapsedTime = PR_Now();
|
||||
|
||||
if (!sync) {
|
||||
rv = transport->AsyncWrite(new TestProvider(buffer), nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("failed calling: AsyncWrite!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Enter the message pump to allow the URL load to proceed.
|
||||
while ( gKeepRunning ) {
|
||||
|
||||
#ifdef WIN32
|
||||
MSG msg;
|
||||
|
||||
if (GetMessage(&msg, NULL, 0, 0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
} else {
|
||||
} else
|
||||
gKeepRunning = FALSE;
|
||||
}
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
/* Mac stuff is missing here! */
|
||||
#else
|
||||
#ifdef XP_OS2
|
||||
QMSG qmsg;
|
||||
|
||||
if (WinGetMsg(0, &qmsg, 0, 0, 0))
|
||||
WinDispatchMsg(0, &qmsg);
|
||||
else
|
||||
gKeepRunning = FALSE;
|
||||
#else
|
||||
PLEvent *gEvent;
|
||||
rv = gEventQ->GetEvent(&gEvent);
|
||||
rv = gEventQ->WaitForEvent(&gEvent);
|
||||
rv = gEventQ->HandleEvent(gEvent);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else {
|
||||
// synchronous write
|
||||
{
|
||||
nsCOMPtr<nsIOutputStream> os;
|
||||
rv = transport->OpenOutputStream(getter_AddRefs(os));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = WriteRequest(os, buffer);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
// synchronous read
|
||||
{
|
||||
nsCOMPtr<nsIInputStream> is;
|
||||
rv = transport->OpenInputStream(getter_AddRefs(is));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = ReadResponse(is);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
}
|
||||
|
||||
PRTime endTime;
|
||||
endTime = PR_Now();
|
||||
printf("Elapsed time: %d\n", (PRInt32)(endTime/1000UL-gElapsedTime/1000UL));
|
||||
LOG(("Elapsed time: %d\n", (PRInt32)(endTime/1000UL - gElapsedTime/1000UL)));
|
||||
|
||||
sts->Shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#if defined(XP_MAC)
|
||||
#include "macstdlibextras.h"
|
||||
|
@ -431,7 +432,7 @@ nsresult TestConnection::WriteBuffer(void)
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mTransport->SetTransferCount(bytesWritten);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = mTransport->AsyncWrite(mStream, /* mOutputObserver */ nsnull, mTransport);
|
||||
rv = NS_AsyncWriteFromStream(mTransport, mStream, nsnull, mTransport);
|
||||
}
|
||||
}
|
||||
// Wait for the write to complete...
|
||||
|
|
|
@ -271,7 +271,7 @@ nsCachedChromeChannel::AsyncRead(nsIStreamListener *listener, nsISupports *ctxt)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCachedChromeChannel::AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt)
|
||||
nsCachedChromeChannel::AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt)
|
||||
{
|
||||
NS_NOTREACHED("don't do that");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -349,7 +349,7 @@ public:
|
|||
NS_IMETHOD OpenOutputStream(nsIOutputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
||||
NS_IMETHOD AsyncOpen(nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncRead(nsIStreamListener *listener, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncWrite(nsIInputStream *fromStream, nsIStreamObserver *observer, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD AsyncWrite(nsIStreamProvider *provider, nsISupports *ctxt) { return NS_OK; }
|
||||
NS_IMETHOD GetLoadAttributes(nsLoadFlags *aLoadAttributes) { *aLoadAttributes = nsIChannel::LOAD_NORMAL; return NS_OK; }
|
||||
NS_IMETHOD SetLoadAttributes(nsLoadFlags aLoadAttributes) { return NS_OK; }
|
||||
NS_IMETHOD GetContentType(char * *aContentType) { *aContentType = nsnull; return NS_OK; }
|
||||
|
|
|
@ -403,6 +403,10 @@ nsPipe::nsPipeInputStream::ReadSegments(nsWriteSegmentFun writer,
|
|||
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK)
|
||||
goto done;
|
||||
NS_ASSERTION(writeCount <= readBufferLen, "writer returned bad writeCount");
|
||||
#ifdef DEBUG
|
||||
if (writeCount > 0 && rv == NS_BASE_STREAM_WOULD_BLOCK)
|
||||
NS_WARNING("Invalid writer implementation: cannot write data and return WOULD_BLOCK");
|
||||
#endif
|
||||
readBuffer += writeCount;
|
||||
readBufferLen -= writeCount;
|
||||
*readCount += writeCount;
|
||||
|
@ -432,6 +436,15 @@ nsPipe::nsPipeInputStream::ReadSegments(nsWriteSegmentFun writer,
|
|||
goto done;
|
||||
}
|
||||
}
|
||||
else if (pipe->mReadCursor == pipe->mWriteCursor) {
|
||||
if (mObserver) {
|
||||
mon.Exit(); // XXXbe avoid deadlock better
|
||||
rv = mObserver->OnEmpty(this);
|
||||
mon.Enter();
|
||||
if (NS_FAILED(rv))
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
done:
|
||||
|
||||
|
|
|
@ -152,6 +152,8 @@ public:
|
|||
PRUint32 count;
|
||||
PRUint32 total = 0;
|
||||
while (PR_TRUE) {
|
||||
//if (gTrace)
|
||||
// printf("calling Read\n");
|
||||
rv = mIn->Read(buf, 100, &count);
|
||||
if (NS_FAILED(rv)) {
|
||||
printf("read failed\n");
|
||||
|
@ -231,7 +233,9 @@ TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
|
|||
if (gTrace)
|
||||
printf("wrote %d bytes: %s\n", writeCount, buf);
|
||||
PR_smprintf_free(buf);
|
||||
//printf("calling Flush\n");
|
||||
out->Flush();
|
||||
//printf("calling WaitForReceipt\n");
|
||||
PRUint32 received = receiver->WaitForReceipt();
|
||||
NS_ASSERTION(received == writeCount, "received wrong amount");
|
||||
}
|
||||
|
@ -292,7 +296,7 @@ TestPipeObserver()
|
|||
printf("TestPipeObserver: OnWrite and OnFull should be called once, OnEmpty should be called twice.\n");
|
||||
nsIInputStream* in;
|
||||
nsIOutputStream* out;
|
||||
rv = NS_NewPipe(&in, &out, 20, 20, PR_TRUE, PR_TRUE);
|
||||
rv = NS_NewPipe(&in, &out, 18, 36, PR_TRUE, PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = in->SetObserver(obs);
|
||||
|
@ -302,27 +306,55 @@ TestPipeObserver()
|
|||
|
||||
char buf[] = "puirt a beul: a style of Gaelic vocal music intended for dancing.";
|
||||
PRUint32 cnt;
|
||||
// this should print OnWrite message:
|
||||
printf("> should see OnWrite message:\n");
|
||||
rv = out->Write(buf, 20, &cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ASSERTION(cnt == 20, "Write failed");
|
||||
|
||||
// this should print OnFull message:
|
||||
rv = out->Write(buf + 20, 1, &cnt);
|
||||
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) return rv;
|
||||
NS_ASSERTION(cnt == 0 && rv == NS_BASE_STREAM_WOULD_BLOCK, "Write failed");
|
||||
|
||||
char buf2[20];
|
||||
rv = in->Read(buf2, 20, &cnt);
|
||||
printf("> should see OnWrite message followed by OnFull message:\n");
|
||||
rv = out->Write(buf + 20, 20, &cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ASSERTION(cnt == 20, "Read failed");
|
||||
NS_ASSERTION(nsCRT::strncmp(buf, buf2, 20) == 0, "Read wrong stuff");
|
||||
NS_ASSERTION(cnt == 16, "Write failed");
|
||||
|
||||
// this should print OnEmpty message:
|
||||
rv = in->Read(buf2, 1, &cnt);
|
||||
rv = in->Available(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
printf("available = %u\n", cnt);
|
||||
NS_ASSERTION(cnt == 36, "Available failed");
|
||||
|
||||
char buf2[40];
|
||||
printf("> should see OnEmpty message:\n");
|
||||
rv = in->Read(buf2, 40, &cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
printf("cnt = %u\n", cnt);
|
||||
NS_ASSERTION(cnt == 36, "Read failed");
|
||||
NS_ASSERTION(nsCRT::strncmp(buf, buf2, 36) == 0, "Read wrong stuff");
|
||||
|
||||
rv = in->Available(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
printf("available = %u\n", cnt);
|
||||
NS_ASSERTION(cnt == 0, "Available failed");
|
||||
|
||||
printf("> should see OnEmpty message:\n");
|
||||
rv = in->Read(buf2, 2, &cnt);
|
||||
if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) return rv;
|
||||
NS_ASSERTION(cnt == 0 && rv == NS_BASE_STREAM_WOULD_BLOCK, "Read failed");
|
||||
|
||||
printf("> should see OnWrite message:\n");
|
||||
rv = out->Write(buf, 20, &cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ASSERTION(cnt == 20, "Write failed");
|
||||
|
||||
rv = in->Available(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
printf("available = %u\n", cnt);
|
||||
NS_ASSERTION(cnt == 20, "Available failed");
|
||||
|
||||
printf("> should see OnEmpty message:\n");
|
||||
rv = in->Read(buf2, 20, &cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_ASSERTION(cnt == 20, "Read failed");
|
||||
|
||||
printf("> should see OnClose message:\n");
|
||||
NS_RELEASE(obs);
|
||||
NS_RELEASE(in);
|
||||
NS_RELEASE(out);
|
||||
|
|
|
@ -202,7 +202,7 @@ nsStreamXferOp::Start( void ) {
|
|||
|
||||
// hand the output channel our input stream. it will take care
|
||||
// of reading data from the stream and writing it to disk.
|
||||
rv = mOutputChannel->AsyncWrite(inStream, NS_STATIC_CAST(nsIStreamObserver*,this), nsnull);
|
||||
rv = NS_AsyncWriteFromStream(mOutputChannel, inStream, NS_STATIC_CAST(nsIStreamObserver*,this), nsnull);
|
||||
if ( NS_FAILED( rv ) ) {
|
||||
this->OnError( kOpAsyncWrite, rv );
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче