Separated the Event Sink from the nsIStreamListener...

This commit is contained in:
rpotts%netscape.com 1999-06-16 09:40:40 +00:00
parent ca75ffcd33
commit ce2c24bc6a
5 changed files with 165 additions and 104 deletions

View File

@ -19,7 +19,7 @@
#ifndef _nsIHTTPEventSink_h_
#define _nsIHTTPEventSink_h_
#include "nsIStreamListener.h"
#include "nsISupports.h"
/*
The nsIHTTPEventSink class is the interface thru which the
@ -27,7 +27,7 @@
-Gagan Saksena 02/25/99
*/
class nsIHTTPEventSink : public nsIStreamListener
class nsIHTTPEventSink : public nsISupports
{
public:

View File

@ -24,6 +24,7 @@
#include "nsHTTPResponse.h"
#include "nsIChannel.h"
#include "nsIInputStream.h"
#include "nsIStreamListener.h"
#include "nsIHttpNotify.h"
#include "nsINetModRegEntry.h"
@ -172,7 +173,25 @@ nsHTTPChannel::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
nsIEventQueue *eventQueue,
nsIStreamListener *listener)
{
return Open();
nsresult rv = NS_OK;
// Initial parameter checks...
if (m_pResponseDataListener) {
rv = NS_ERROR_IN_PROGRESS;
}
else if (!listener) {
rv = NS_ERROR_NULL_POINTER;
}
// Initiate the loading of the URL...
if (NS_SUCCEEDED(rv)) {
m_pResponseDataListener = listener;
NS_ADDREF(m_pResponseDataListener);
rv = Open();
}
return rv;
}
NS_IMETHODIMP
@ -260,16 +279,16 @@ nsHTTPChannel::SetRequestMethod(PRUint32/*HTTPMethod*/ i_Method)
NS_IMETHODIMP
nsHTTPChannel::GetResponseDataListener(nsIStreamListener* *aListener)
{
nsresult rv = NS_OK;
nsresult rv = NS_OK;
if (aListener) {
*aListener = m_pResponseDataListener;
NS_IF_ADDREF(m_pResponseDataListener);
} else {
rv = NS_ERROR_NULL_POINTER;
}
if (aListener) {
*aListener = m_pResponseDataListener;
NS_IF_ADDREF(m_pResponseDataListener);
} else {
rv = NS_ERROR_NULL_POINTER;
}
return rv;
return rv;
}

View File

@ -40,6 +40,7 @@ nsHTTPResponseListener::nsHTTPResponseListener():
m_pConnection(nsnull),
m_bFirstLineParsed(PR_FALSE),
m_pResponse(nsnull),
m_pConsumer(nsnull),
m_ReadLength(0),
m_bHeadersDone(PR_FALSE)
{
@ -48,10 +49,9 @@ nsHTTPResponseListener::nsHTTPResponseListener():
nsHTTPResponseListener::~nsHTTPResponseListener()
{
if (m_pConnection)
NS_RELEASE(m_pConnection);
if (m_pResponse)
NS_RELEASE(m_pResponse);
NS_IF_RELEASE(m_pConnection);
NS_IF_RELEASE(m_pResponse);
NS_IF_RELEASE(m_pConsumer);
}
NS_IMPL_ISUPPORTS(nsHTTPResponseListener,nsIStreamListener::GetIID());
@ -67,10 +67,6 @@ nsHTTPResponseListener::OnDataAvailable(nsISupports* context,
PRUint32 i_Length)
{
nsresult rv = NS_OK;
// Should I save this as a member variable? yes... todo
nsIHTTPEventSink* pSink= nsnull;
m_pConnection->GetEventSink(&pSink);
NS_VERIFY(pSink, "No HTTP Event Sink!");
NS_ASSERTION(i_pStream, "Fake stream!");
/// NS_ASSERTION(i_SourceOffset == 0, "Source shifted already?!");
@ -192,32 +188,21 @@ nsHTTPResponseListener::OnDataAvailable(nsISupports* context,
if (m_bHeadersDone)
{
nsIStreamListener* internalListener = nsnull;
// Get our end of the pipe between us and the user's GetInputStream()
rv = m_pConnection->GetResponseDataListener(&internalListener);
if (internalListener) {
// post the data to the stream listener
// XXX this is the wrong data and offsets I think.
rv = internalListener->OnDataAvailable(context, i_pStream, 0, i_Length);
NS_RELEASE(internalListener);
if (NS_FAILED(rv))
return rv;
// Pass the notification out to the consumer...
NS_ASSERTION(m_pConsumer, "No Stream Listener!");
if (m_pConsumer) {
// XXX: This is the wrong context being passed out to the consumer
rv = m_pConsumer->OnDataAvailable(context, i_pStream, 0, i_Length);
}
// do whatever we want for the event sink
rv = pSink->OnDataAvailable(context, i_pStream, 0, i_Length);
return rv;
}
return NS_OK;
return rv;
}
NS_IMETHODIMP
nsHTTPResponseListener::OnStartBinding(nsISupports* i_pContext)
{
nsresult rv;
nsIHTTPEventSink* pSink= nsnull;
//TODO globally replace printf with trace calls.
//printf("nsHTTPResponseListener::OnStartBinding...\n");
@ -226,6 +211,7 @@ nsHTTPResponseListener::OnStartBinding(nsISupports* i_pContext)
m_bHeadersDone = PR_FALSE;
m_bFirstLineParsed = PR_FALSE;
// Cache the nsIHTTPChannel...
if (i_pContext) {
rv = i_pContext->QueryInterface(nsIHTTPChannel::GetIID(),
(void**)&m_pConnection);
@ -233,17 +219,17 @@ nsHTTPResponseListener::OnStartBinding(nsISupports* i_pContext)
rv = NS_ERROR_NULL_POINTER;
}
// Cache the nsIStreamListener of the consumer...
if (NS_SUCCEEDED(rv)) {
// XXX: EventSink(...) should AddRef the returned pointer...
rv = m_pConnection->GetEventSink(&pSink);
if (NS_FAILED(rv)) {
NS_ERROR("No HTTP Event Sink!");
}
rv = m_pConnection->GetResponseDataListener(&m_pConsumer);
}
if (NS_SUCCEEDED(rv)) {
rv = pSink->OnStartBinding(i_pContext);
NS_ASSERTION(m_pConsumer, "No Stream Listener!");
// Pass the notification out to the consumer...
if (m_pConsumer) {
// XXX: This is the wrong context being passed out to the consumer
rv = m_pConsumer->OnStartBinding(i_pContext);
}
return rv;
@ -254,15 +240,17 @@ nsHTTPResponseListener::OnStopBinding(nsISupports* i_pContext,
nsresult i_Status,
const PRUnichar* i_pMsg)
{
nsresult rv;
//printf("nsHTTPResponseListener::OnStopBinding...\n");
//NS_ASSERTION(m_pResponse, "Response object not created yet or died?!");
// Should I save this as a member variable? yes... todo
nsIHTTPEventSink* pSink= nsnull;
nsresult rv = m_pConnection->GetEventSink(&pSink);
if (NS_FAILED(rv))
NS_ERROR("No HTTP Event Sink!");
rv = pSink->OnStopBinding(i_pContext, i_Status,i_pMsg);
NS_ASSERTION(m_pConsumer, "No Stream Listener!");
// Pass the notification out to the consumer...
if (m_pConsumer) {
// XXX: This is the wrong context being passed out to the consumer
rv = m_pConsumer->OnStopBinding(i_pContext, i_Status, i_pMsg);
}
return rv;
}

View File

@ -75,6 +75,7 @@ protected:
PRBool m_bFirstLineParsed;
nsHTTPResponse* m_pResponse;
nsIHTTPChannel* m_pConnection;
nsIStreamListener* m_pConsumer;
PRUint32 m_ReadLength; // Already read
};

View File

@ -52,12 +52,12 @@ static PRTime gElapsedTime;
static int gKeepRunning = 1;
static nsIEventQueue* gEventQ = nsnull;
class InputTestConsumer : public nsIHTTPEventSink
class TestHTTPEventSink : public nsIHTTPEventSink
{
public:
InputTestConsumer();
virtual ~InputTestConsumer();
TestHTTPEventSink();
virtual ~TestHTTPEventSink();
// ISupports interface...
NS_DECL_ISUPPORTS
@ -74,6 +74,88 @@ public:
// OnRedirect gets fired only if you have set FollowRedirects on the handler!
NS_IMETHOD OnRedirect(nsISupports* i_Context,
nsIURI* i_NewLocation);
/*
// IStreamListener interface...
NS_IMETHOD OnStartBinding(nsISupports* context) { NS_ERROR("bad..."); return NS_ERROR_FAILURE; }
NS_IMETHOD OnDataAvailable(nsISupports* context,
nsIBufferInputStream *aIStream,
PRUint32 aSourceOffset,
PRUint32 aLength) { NS_ERROR("bad..."); return NS_ERROR_FAILURE; }
NS_IMETHOD OnStopBinding(nsISupports* context,
nsresult aStatus,
const PRUnichar* aMsg) { NS_ERROR("bad..."); return NS_ERROR_FAILURE; }
NS_IMETHOD OnStartRequest(nsISupports* context) { NS_ERROR("bad..."); return NS_ERROR_FAILURE; }
NS_IMETHOD OnStopRequest(nsISupports* context,
nsresult aStatus,
const PRUnichar* aMsg) { NS_ERROR("bad..."); return NS_ERROR_FAILURE; }
*/
};
TestHTTPEventSink::TestHTTPEventSink()
{
NS_INIT_REFCNT();
}
TestHTTPEventSink::~TestHTTPEventSink()
{
}
NS_IMPL_ISUPPORTS(TestHTTPEventSink,nsIHTTPEventSink::GetIID());
NS_IMETHODIMP
TestHTTPEventSink::OnAwaitingInput(nsISupports* context)
{
printf("\n+++ TestHTTPEventSink::OnAwaitingInput +++\n");
return NS_OK;
}
NS_IMETHODIMP
TestHTTPEventSink::OnHeadersAvailable(nsISupports* context)
{
printf("\n+++ TestHTTPEventSink::OnHeadersAvailable +++\n");
nsCOMPtr<nsIHTTPChannel> pHTTPCon(do_QueryInterface(context));
if (pHTTPCon)
{
char* type;
//optimize later TODO allow atoms here...! intead of just the header strings
pHTTPCon->GetResponseHeader("Content-type", &type);
if (type) {
printf("\nRecieving ... %s\n", type);
nsCRT::free(type);
}
}
return NS_OK;
}
NS_IMETHODIMP
TestHTTPEventSink::OnProgress(nsISupports* context, PRUint32 i_Progress, PRUint32 i_ProgressMax)
{
printf("\n+++ TestHTTPEventSink::OnProgress +++\n");
return NS_OK;
}
NS_IMETHODIMP
TestHTTPEventSink::OnRedirect(nsISupports* context, nsIURI* i_NewLocation)
{
printf("\n+++ TestHTTPEventSink::OnRedirect +++\n");
return NS_OK;
}
class InputTestConsumer : public nsIStreamListener
{
public:
InputTestConsumer();
virtual ~InputTestConsumer();
// ISupports interface...
NS_DECL_ISUPPORTS
// IStreamListener interface...
NS_IMETHOD OnStartBinding(nsISupports* context);
@ -110,8 +192,7 @@ InputTestConsumer::~InputTestConsumer()
}
//NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
NS_IMPL_ISUPPORTS(InputTestConsumer,nsIHTTPEventSink::GetIID());
NS_IMPL_ISUPPORTS(InputTestConsumer,nsIStreamListener::GetIID());
NS_IMETHODIMP
@ -150,60 +231,25 @@ InputTestConsumer::OnStopBinding(nsISupports* context,
return NS_OK;
}
NS_IMETHODIMP
InputTestConsumer::OnAwaitingInput(nsISupports* context)
{
printf("\n+++ InputTestConsumer::OnAwaitingInput +++\n");
return NS_OK;
}
NS_IMETHODIMP
InputTestConsumer::OnHeadersAvailable(nsISupports* context)
{
printf("\n+++ InputTestConsumer::OnHeadersAvailable +++\n");
nsCOMPtr<nsIHTTPChannel> pHTTPCon(do_QueryInterface(context));
if (pHTTPCon)
{
char* type;
//optimize later TODO allow atoms here...! intead of just the header strings
pHTTPCon->GetResponseHeader("Content-type", &type);
if (type) {
printf("\nRecieving ... %s\n", type);
nsCRT::free(type);
}
}
return NS_OK;
}
NS_IMETHODIMP
InputTestConsumer::OnProgress(nsISupports* context, PRUint32 i_Progress, PRUint32 i_ProgressMax)
{
printf("\n+++ InputTestConsumer::OnProgress +++\n");
return NS_OK;
}
NS_IMETHODIMP
InputTestConsumer::OnRedirect(nsISupports* context, nsIURI* i_NewLocation)
{
printf("\n+++ InputTestConsumer::OnRedirect +++\n");
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
class nsEventSinkGetter : public nsIEventSinkGetter {
public:
NS_DECL_ISUPPORTS
nsEventSinkGetter() {
NS_INIT_REFCNT();
}
NS_IMETHOD GetEventSink(const char* verb, const nsIID& eventSinkIID,
nsISupports* *result) {
nsresult rv = NS_ERROR_FAILURE;
if (nsCRT::strcmp(verb, "load") == 0) { // makeshift verb for now
if (eventSinkIID.Equals(nsIHTTPEventSink::GetIID())) {
InputTestConsumer *sink;
TestHTTPEventSink *sink;
sink = new InputTestConsumer();
sink = new TestHTTPEventSink();
if (sink) {
NS_ADDREF(sink);
rv = sink->QueryInterface(eventSinkIID, (void**)result);
@ -296,21 +342,28 @@ main(int argc, char* argv[])
}
// But calling the open is required!
pChannel->Open();
/*
pChannel->AsyncRead(0, // staring position
-1, // number of bytes to read
nsnull, // ISupports context
gEventQ, // nsIEventQ for marshalling
nsnull); // IStreamListener consumer
*/
/// pChannel->Open();
InputTestConsumer* listener;
listener = new InputTestConsumer;
NS_IF_ADDREF(listener);
rv = pChannel->AsyncRead(0, // staring position
-1, // number of bytes to read
nsnull, // ISupports context
gEventQ, // nsIEventQ for marshalling
listener); // IStreamListener consumer
NS_IF_RELEASE(listener);
}
} else {
printf("NewChannelFromURI failed!\n");
return -1;
}
}
} else {
printf("NewURI failed!\n");
return -1;
}
}