зеркало из https://github.com/mozilla/pjs.git
(not part of the seamonkey build)
define and implement nsDocumentOpenInfo. Implement uri loader::OpenURI. This is the first pass at my implementation it isn't complete and it doesn't use the registry for getting protocol handlers and content handlers yet...but it's a start
This commit is contained in:
Родитель
af661431f1
Коммит
8824e33e62
|
@ -17,10 +17,135 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nsURILoader.h"
|
#include "nsURILoader.h"
|
||||||
|
#include "nsIURIContentListener.h"
|
||||||
|
#include "nsILoadGroup.h"
|
||||||
|
#include "nsIIOService.h"
|
||||||
|
#include "nsIServiceManager.h"
|
||||||
|
#include "nsIStreamListener.h"
|
||||||
|
#include "nsIChannel.h"
|
||||||
|
|
||||||
|
|
||||||
#include "nsVoidArray.h"
|
#include "nsVoidArray.h"
|
||||||
#include "nsXPIDLString.h"
|
#include "nsXPIDLString.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
|
||||||
|
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
||||||
|
static NS_DEFINE_CID(kURILoaderCID, NS_URI_LOADER_CID);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The nsDocumentOpenInfo contains the state required when a single document
|
||||||
|
* is being opened in order to discover the content type... Each instance remains alive until its target URL has
|
||||||
|
* been loaded (or aborted).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class nsDocumentOpenInfo : public nsIStreamObserver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsDocumentOpenInfo();
|
||||||
|
|
||||||
|
nsresult Init(nsIURIContentListener * aContentListener);
|
||||||
|
|
||||||
|
NS_DECL_ISUPPORTS
|
||||||
|
|
||||||
|
nsresult Open(nsIURI *aURL,
|
||||||
|
const char * aCommand,
|
||||||
|
const char * aWindowTarget,
|
||||||
|
nsIEventSinkGetter * aEventSinkGetter,
|
||||||
|
nsILoadGroup* aLoadGroup,
|
||||||
|
nsISupports * aContext,
|
||||||
|
nsIURI * aReferringURI);
|
||||||
|
|
||||||
|
// nsIStreamObserver methods:
|
||||||
|
NS_DECL_NSISTREAMOBSERVER
|
||||||
|
|
||||||
|
// nsIStreamListener methods:
|
||||||
|
// NS_DECL_NSISTREAMLISTENER
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual ~nsDocumentOpenInfo();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIURIContentListener> m_contentListener;
|
||||||
|
nsCOMPtr<nsIChannel> m_channel;
|
||||||
|
nsCString m_command;
|
||||||
|
nsCString m_windowTarget;
|
||||||
|
};
|
||||||
|
|
||||||
|
NS_IMPL_ISUPPORTS1(nsDocumentOpenInfo, nsIStreamObserver);
|
||||||
|
|
||||||
|
nsDocumentOpenInfo::nsDocumentOpenInfo()
|
||||||
|
{
|
||||||
|
NS_INIT_ISUPPORTS();
|
||||||
|
}
|
||||||
|
|
||||||
|
nsDocumentOpenInfo::~nsDocumentOpenInfo()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsDocumentOpenInfo::Init(nsIURIContentListener * aContentListener)
|
||||||
|
{
|
||||||
|
m_contentListener = aContentListener;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsDocumentOpenInfo::Open(nsIURI * aURI, const char * aCommand,
|
||||||
|
const char * aWindowTarget,
|
||||||
|
nsIEventSinkGetter * aEventSinkGetter,
|
||||||
|
nsILoadGroup* aLoadGroup,
|
||||||
|
nsISupports * aContext,
|
||||||
|
nsIURI * aReferringURI)
|
||||||
|
{
|
||||||
|
// this method is not complete!!! Eventually, we should first go
|
||||||
|
// to the content listener and ask them for a protocol handler...
|
||||||
|
// if they don't give us one, we need to go to the registry and get
|
||||||
|
// the preferred protocol handler.
|
||||||
|
|
||||||
|
// But for now, I'm going to let necko do the work for us....
|
||||||
|
|
||||||
|
// store any local state
|
||||||
|
m_command = aCommand;
|
||||||
|
m_windowTarget = aWindowTarget;
|
||||||
|
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
NS_WITH_SERVICE(nsIIOService, pNetService, kIOServiceCID, &rv);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
{
|
||||||
|
nsCOMPtr<nsIChannel> m_channel;
|
||||||
|
rv = pNetService->NewChannelFromURI(aCommand, aURI, aLoadGroup, aEventSinkGetter, aReferringURI, getter_AddRefs(m_channel));
|
||||||
|
if (NS_FAILED(rv)) return rv; // uhoh we were unable to get a channel to handle the url!!!
|
||||||
|
rv = m_channel->AsyncOpen(this, aContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsDocumentOpenInfo::OnStartRequest(nsIChannel * aChannel, nsISupports * aCtxt)
|
||||||
|
{
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
nsXPIDLCString aContentType;
|
||||||
|
rv = aChannel->GetContentType(getter_Copies(aContentType));
|
||||||
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
|
// go to the uri dispatcher and give them our stuff...
|
||||||
|
NS_WITH_SERVICE(nsIURILoader, pURILoader, kURILoaderCID, &rv);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
rv = pURILoader->DispatchContent(aContentType, m_command, m_windowTarget,
|
||||||
|
aChannel, aCtxt, m_contentListener);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsDocumentOpenInfo::OnStopRequest(nsIChannel * aChannel, nsISupports *aCtxt,
|
||||||
|
nsresult aStatus, const PRUnichar * errorMsg)
|
||||||
|
{
|
||||||
|
// what are we going to do if we get a failure code here...that means the open may have failed
|
||||||
|
// and we never discovered the content type....so the uri never really was run!!!! uhoh..
|
||||||
|
|
||||||
|
// this method is incomplete until I figure that stuff out.
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsURILoader::nsURILoader()
|
nsURILoader::nsURILoader()
|
||||||
{
|
{
|
||||||
NS_INIT_ISUPPORTS();
|
NS_INIT_ISUPPORTS();
|
||||||
|
@ -54,10 +179,88 @@ NS_IMETHODIMP nsURILoader::UnRegisterContentListener(nsIURIContentListener * aCo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsURILoader::OpenURI(nsIURI *aURI, nsIStreamObserver *aStreamObserver,
|
NS_IMETHODIMP nsURILoader::OpenURI(nsIURI *aURI,
|
||||||
nsIURIContentListener *aContentListener, nsISupports *aContext,
|
const char * aCommand,
|
||||||
nsIURI *aReferringURI)
|
const char * aWindowTarget,
|
||||||
|
nsIEventSinkGetter *aEventSinkGetter,
|
||||||
|
nsILoadGroup * aLoadGroup,
|
||||||
|
nsISupports *aContext,
|
||||||
|
nsIURIContentListener *aContentListener,
|
||||||
|
nsIURI *aReferringURI)
|
||||||
{
|
{
|
||||||
|
// we need to create a DocumentOpenInfo object which will go ahead and open the url
|
||||||
|
// and discover the content type....
|
||||||
|
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
nsDocumentOpenInfo* loader = nsnull;
|
||||||
|
|
||||||
|
if (!aURI) return NS_ERROR_NULL_POINTER;
|
||||||
|
|
||||||
|
NS_NEWXPCOM(loader, nsDocumentOpenInfo);
|
||||||
|
if (!loader) return NS_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
NS_ADDREF(loader);
|
||||||
|
loader->Init(aContentListener); // Extra Info
|
||||||
|
|
||||||
|
// now instruct the loader to go ahead and open the url
|
||||||
|
rv = loader->Open(aURI, aCommand, aWindowTarget, aEventSinkGetter, aLoadGroup, aContext, aReferringURI);
|
||||||
|
NS_RELEASE(loader);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult nsURILoader::DispatchContent(const char * aContentType,
|
||||||
|
const char * aCommand,
|
||||||
|
const char * aWindowTarget,
|
||||||
|
nsIChannel * aChannel,
|
||||||
|
nsISupports * aCtxt,
|
||||||
|
nsIURIContentListener * aContentListener)
|
||||||
|
{
|
||||||
|
// okay, now we've discovered the content type. We need to do the following:
|
||||||
|
// (1) Give our uri content listener first crack at handling this content type.
|
||||||
|
nsresult rv = NS_OK;
|
||||||
|
|
||||||
|
nsCOMPtr<nsIStreamListener> aContentStreamListener;
|
||||||
|
PRBool aAbortProcess = PR_FALSE;
|
||||||
|
if (aContentListener)
|
||||||
|
rv = aContentListener->DoContent(aContentType, aCommand, aWindowTarget,
|
||||||
|
aChannel, getter_AddRefs(aContentStreamListener),
|
||||||
|
&aAbortProcess);
|
||||||
|
|
||||||
|
// the listener is doing all the work from here...we are done!!!
|
||||||
|
if (aAbortProcess) return rv;
|
||||||
|
|
||||||
|
// if we didn't get a content stream listener back...then iterate over our registered
|
||||||
|
// stream listeners until we can find one..
|
||||||
|
|
||||||
|
if (!aContentStreamListener)
|
||||||
|
{
|
||||||
|
PRInt32 i = 0;
|
||||||
|
// keep looping until we are told to abort or we get a content listener back
|
||||||
|
for(i = 0; i < m_listeners->Count() && !aAbortProcess && !aContentStreamListener; i++)
|
||||||
|
{
|
||||||
|
aAbortProcess = PR_FALSE;
|
||||||
|
//nsIURIContentListener's aren't refcounted.
|
||||||
|
nsIURIContentListener * listener =(nsIURIContentListener*)m_listeners->ElementAt(i);
|
||||||
|
if (listener)
|
||||||
|
rv = listener->DoContent(aContentType, aCommand, aWindowTarget,
|
||||||
|
aChannel, getter_AddRefs(aContentStreamListener),
|
||||||
|
&aAbortProcess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// okay, all registered listeners have had a chance to handle this content...
|
||||||
|
// did one of them give us a stream listener back? if so, let's start reading data
|
||||||
|
// into it...
|
||||||
|
if (aContentStreamListener)
|
||||||
|
{
|
||||||
|
return aChannel->AsyncRead(0, -1, aCtxt, aContentStreamListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// no registered content listeners to handle this type!!! so go to the register
|
||||||
|
// and get a registered nsIContentHandler for our content type. Hand it off
|
||||||
|
// to them...
|
||||||
|
|
||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче