Making jar: protocol work in general, and OpenInputStream in particular.

git-svn-id: svn://10.0.0.236/trunk@64583 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
warren%netscape.com 2000-03-30 07:39:31 +00:00
parent 094bb4201d
commit e8a3ec30ae
4 changed files with 376 additions and 50 deletions

View File

@ -37,6 +37,23 @@ static NS_DEFINE_CID(kMIMEServiceCID, NS_MIMESERVICE_CID);
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
static NS_DEFINE_CID(kScriptSecurityManagerCID, NS_SCRIPTSECURITYMANAGER_CID);
#if defined(PR_LOGGING)
#include "nsXPIDLString.h"
//
// Log module for SocketTransport logging...
//
// To enable logging (see prlog.h for full details):
//
// set NSPR_LOG_MODULES=nsJarProtocol:5
// set NSPR_LOG_FILE=nspr.log
//
// this enables PR_LOG_DEBUG level information and places all output in
// the file nspr.log
//
PRLogModuleInfo* gJarProtocolLog = nsnull;
#endif /* PR_LOGGING */
////////////////////////////////////////////////////////////////////////////////
class nsJARDownloadObserver : public nsIStreamObserver
@ -56,6 +73,19 @@ public:
nsresult rv = NS_OK;
nsAutoMonitor monitor(mJARChannel->mMonitor);
#ifdef PR_LOGGING
nsCOMPtr<nsIURI> jarURI;
rv = jarCacheTransport->GetURI(getter_AddRefs(jarURI));
if (NS_SUCCEEDED(rv)) {
nsXPIDLCString jarURLStr;
rv = jarURI->GetSpec(getter_Copies(jarURLStr));
if (NS_SUCCEEDED(rv)) {
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar download complete %s status=%x",
(const char*)jarURLStr, status));
}
}
#endif
if (NS_SUCCEEDED(status) && mJARChannel->mJarCacheTransport) {
NS_ASSERTION(jarCacheTransport == (mJARChannel->mJarCacheTransport).get(),
"wrong transport");
@ -78,13 +108,16 @@ public:
rv = jarCacheFile->SetNotificationCallbacks(mJARChannel->mCallbacks);
if (NS_FAILED(rv)) return rv;
rv = mJARChannel->ExtractJARElement(jarCacheFile);
mJARChannel->SetJARBaseFile(jarCacheFile);
rv = mOnJARFileAvailable(mJARChannel, mClosure);
}
mJARChannel->mJarCacheTransport = nsnull;
return rv;
}
nsJARDownloadObserver(nsIFile* jarCacheFile, nsJARChannel* jarChannel) {
nsJARDownloadObserver(nsIFile* jarCacheFile, nsJARChannel* jarChannel,
OnJARFileAvailableFun onJARFileAvailable,
void* closure) {
NS_INIT_REFCNT();
mJarCacheFile = jarCacheFile;
mJARChannel = jarChannel;
@ -96,8 +129,10 @@ public:
}
protected:
nsCOMPtr<nsIFile> mJarCacheFile;
nsJARChannel* mJARChannel;
nsCOMPtr<nsIFile> mJarCacheFile;
nsJARChannel* mJARChannel;
OnJARFileAvailableFun mOnJARFileAvailable;
void* mClosure;
};
NS_IMPL_ISUPPORTS1(nsJARDownloadObserver, nsIStreamObserver)
@ -106,11 +141,24 @@ NS_IMPL_ISUPPORTS1(nsJARDownloadObserver, nsIStreamObserver)
nsJARChannel::nsJARChannel()
: mContentType(nsnull),
mContentLength(-1),
mStartPosition(0),
mReadCount(-1),
mJAREntry(nsnull),
mMonitor(nsnull),
mStatus(NS_OK)
{
NS_INIT_REFCNT();
#if defined(PR_LOGGING)
//
// Initialize the global PRLogModule for socket transport logging
// if necessary...
//
if (nsnull == gJarProtocolLog) {
gJarProtocolLog = PR_NewLogModule("nsJarProtocol");
}
#endif /* PR_LOGGING */
}
nsJARChannel::~nsJARChannel()
@ -270,11 +318,30 @@ nsJARChannel::SetURI(nsIURI* aURI)
return rv;
}
static nsresult
OpenJARElement(nsJARChannel* channel, void* closure)
{
nsresult rv;
nsIInputStream* *result = (nsIInputStream**)closure;
nsAutoCMonitor mon(channel);
rv = channel->Open(nsnull, nsnull);
if (NS_FAILED(rv)) return rv;
rv = channel->GetInputStream(result);
mon.Notify(); // wake up OpenInputStream
return rv;
}
NS_IMETHODIMP
nsJARChannel::OpenInputStream(nsIInputStream* *result)
{
NS_NOTREACHED("nsJARChannel::OpenInputStream");
return NS_ERROR_NOT_IMPLEMENTED;
nsAutoCMonitor mon(this);
nsresult rv;
*result = nsnull;
rv = EnsureJARFileAvailable(OpenJARElement, result);
if (NS_FAILED(rv)) return rv;
if (*result == nsnull)
mon.Wait();
return rv;
}
NS_IMETHODIMP
@ -291,10 +358,35 @@ nsJARChannel::AsyncOpen(nsIStreamObserver* observer, nsISupports* ctxt)
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult
ReadJARElement(nsJARChannel* channel, void* closure)
{
nsresult rv;
rv = channel->AsyncReadJARElement();
return rv;
}
NS_IMETHODIMP
nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
{
mUserContext = ctxt;
mUserListener = listener;
return EnsureJARFileAvailable(ReadJARElement, nsnull);
}
nsresult
nsJARChannel::EnsureJARFileAvailable(OnJARFileAvailableFun onJARFileAvailable,
void* closure)
{
nsresult rv;
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: EnsureJARFileAvailable %s", (const char*)jarURLStr));
#endif
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
if (NS_FAILED(rv)) return rv;
@ -315,14 +407,13 @@ nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
if (mLoadGroup)
(void)mLoadGroup->AddChannel(this, nsnull);
// XXX need to set a state variable here to say we're reading
mUserContext = ctxt;
mUserListener = listener;
mJARBaseFile = do_QueryInterface(jarBaseChannel, &rv);
nsCOMPtr<nsIFileChannel> jarBaseFile = do_QueryInterface(jarBaseChannel, &rv);
if (NS_SUCCEEDED(rv)) {
// then we've already got a local jar file -- no need to download it
rv = ExtractJARElement(jarBaseFile);
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: extracting local jar file %s", (const char*)jarURLStr));
rv = onJARFileAvailable(this, closure);
}
else {
// otherwise, we need to download the jar file
@ -338,18 +429,19 @@ nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
if (NS_SUCCEEDED(rv) && filePresent)
{
// then we've already got the file in the local cache -- no need to download it
nsCOMPtr<nsIFileChannel> fileChannel;
rv = NS_NewLocalFileChannel(getter_AddRefs(fileChannel),
rv = NS_NewLocalFileChannel(getter_AddRefs(mJARBaseFile),
jarCacheFile,
PR_RDONLY,
0);
if (NS_FAILED(rv)) return rv;
rv = fileChannel->SetBufferSegmentSize(mBufferSegmentSize);
rv = mJARBaseFile->SetBufferSegmentSize(mBufferSegmentSize);
if (NS_FAILED(rv)) return rv;
rv = fileChannel->SetBufferMaxSize(mBufferMaxSize);
rv = mJARBaseFile->SetBufferMaxSize(mBufferMaxSize);
if (NS_FAILED(rv)) return rv;
rv = ExtractJARElement(fileChannel);
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar file already in cache %s", (const char*)jarURLStr));
rv = onJARFileAvailable(this, closure);
return rv;
}
@ -372,10 +464,13 @@ nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
rv = mJarCacheTransport->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamObserver> downloadObserver = new nsJARDownloadObserver(jarCacheFile, this);
nsCOMPtr<nsIStreamObserver> downloadObserver =
new nsJARDownloadObserver(jarCacheFile, this, onJARFileAvailable, closure);
if (downloadObserver == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: downloading jar file %s", (const char*)jarURLStr));
nsCOMPtr<nsIInputStream> jarBaseIn;
rv = jarBaseChannel->OpenInputStream(getter_AddRefs(jarBaseIn));
if (NS_FAILED(rv)) return rv;
@ -422,13 +517,32 @@ nsJARChannel::GetCacheFile(nsIFile* *cacheFile)
}
nsresult
nsJARChannel::ExtractJARElement(nsIFileChannel* jarBaseFile)
nsJARChannel::AsyncReadJARElement()
{
nsresult rv;
nsAutoMonitor monitor(mMonitor);
mJARBaseFile = jarBaseFile;
NS_ASSERTION(mJARBaseFile, "mJARBaseFile is null");
if (mLoadGroup) {
nsCOMPtr<nsILoadGroupListenerFactory> factory;
//
// Create a load group "proxy" listener...
//
rv = mLoadGroup->GetGroupListenerFactory(getter_AddRefs(factory));
if (factory) {
nsIStreamListener *newListener;
rv = factory->CreateLoadGroupListener(mUserListener, &newListener);
if (NS_SUCCEEDED(rv)) {
mUserListener = newListener;
NS_RELEASE(newListener);
}
}
rv = mLoadGroup->AddChannel(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
@ -444,6 +558,16 @@ nsJARChannel::ExtractJARElement(nsIFileChannel* jarBaseFile)
rv = mJarExtractionTransport->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: AsyncRead jar entry %s", (const char*)jarURLStr));
#endif
rv = mJarExtractionTransport->SetTransferOffset(mStartPosition);
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->SetTransferCount(mReadCount);
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->AsyncRead(this, nsnull);
return rv;
}
@ -723,10 +847,27 @@ nsJARChannel::OnStopRequest(nsIChannel* jarExtractionTransport,
const PRUnichar* aMsg)
{
nsresult rv;
#ifdef PR_LOGGING
nsCOMPtr<nsIURI> jarURI;
nsXPIDLCString jarURLStr;
rv = mURI->GetSpec(getter_Copies(jarURLStr));
if (NS_SUCCEEDED(rv)) {
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar extraction complete %s status=%x",
(const char*)jarURLStr, status));
}
#endif
rv = mUserListener->OnStopRequest(this, mUserContext, status, aMsg);
if (mLoadGroup) {
if (NS_SUCCEEDED(rv)) {
mLoadGroup->RemoveChannel(this, context, status, aMsg);
}
}
mUserListener = nsnull;
mUserContext = nsnull;
mJarExtractionTransport = nsnull;
if (mLoadGroup)
mLoadGroup->RemoveChannel(this, nsnull, rv, nsnull);
return rv;
}
@ -751,6 +892,8 @@ NS_IMETHODIMP
nsJARChannel::Open(char* *contentType, PRInt32 *contentLength)
{
nsresult rv;
NS_ASSERTION(mJARBaseFile, "mJARBaseFile is null");
rv = nsComponentManager::CreateInstance(kZipReaderCID,
nsnull,
NS_GET_IID(nsIZipReader),
@ -774,10 +917,16 @@ nsJARChannel::Open(char* *contentType, PRInt32 *contentLength)
rv = mJAR->GetEntry(mJAREntry, getter_AddRefs(entry));
if (NS_FAILED(rv)) return rv;
rv = entry->GetRealSize((PRUint32*)contentLength);
if (NS_FAILED(rv)) return rv;
if (contentLength) {
rv = entry->GetRealSize((PRUint32*)contentLength);
if (NS_FAILED(rv)) return rv;
}
return GetContentType(contentType);
if (contentType) {
rv = GetContentType(contentType);
if (NS_FAILED(rv)) return rv;
}
return rv;
}
@ -791,6 +940,12 @@ nsJARChannel::Close(nsresult status)
NS_IMETHODIMP
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
{
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: GetInputStream jar entry %s", (const char*)jarURLStr));
#endif
return mJAR->GetInputStream(mJAREntry, aInputStream);
}

View File

@ -38,6 +38,7 @@
#include "prmon.h"
class nsIFileChannel;
class nsJARChannel;
#define NS_JARCHANNEL_CID \
{ /* 0xc7e410d5-0x85f2-11d3-9f63-006008a6efe9 */ \
@ -49,6 +50,9 @@ class nsIFileChannel;
#define JAR_DIRECTORY "jarCache"
typedef nsresult
(*OnJARFileAvailableFun)(nsJARChannel* channel, void* closure);
class nsJARChannel : public nsIJARChannel,
public nsIStreamListener,
public nsIFileSystem
@ -70,9 +74,13 @@ public:
Create(nsISupports* aOuter, REFNSIID aIID, void **aResult);
nsresult Init(nsIJARProtocolHandler* aHandler, nsIURI* uri);
nsresult ExtractJARElement(nsIFileChannel* jarFileChannel);
nsresult EnsureJARFileAvailable(OnJARFileAvailableFun fun,
void* closure);
nsresult AsyncReadJARElement();
nsresult GetCacheFile(nsIFile* *cacheFile);
void SetJARBaseFile(nsIFileChannel* channel) { mJARBaseFile = channel; }
friend class nsJARDownloadObserver;
protected:

View File

@ -37,6 +37,23 @@ static NS_DEFINE_CID(kMIMEServiceCID, NS_MIMESERVICE_CID);
static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
static NS_DEFINE_CID(kScriptSecurityManagerCID, NS_SCRIPTSECURITYMANAGER_CID);
#if defined(PR_LOGGING)
#include "nsXPIDLString.h"
//
// Log module for SocketTransport logging...
//
// To enable logging (see prlog.h for full details):
//
// set NSPR_LOG_MODULES=nsJarProtocol:5
// set NSPR_LOG_FILE=nspr.log
//
// this enables PR_LOG_DEBUG level information and places all output in
// the file nspr.log
//
PRLogModuleInfo* gJarProtocolLog = nsnull;
#endif /* PR_LOGGING */
////////////////////////////////////////////////////////////////////////////////
class nsJARDownloadObserver : public nsIStreamObserver
@ -56,6 +73,19 @@ public:
nsresult rv = NS_OK;
nsAutoMonitor monitor(mJARChannel->mMonitor);
#ifdef PR_LOGGING
nsCOMPtr<nsIURI> jarURI;
rv = jarCacheTransport->GetURI(getter_AddRefs(jarURI));
if (NS_SUCCEEDED(rv)) {
nsXPIDLCString jarURLStr;
rv = jarURI->GetSpec(getter_Copies(jarURLStr));
if (NS_SUCCEEDED(rv)) {
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar download complete %s status=%x",
(const char*)jarURLStr, status));
}
}
#endif
if (NS_SUCCEEDED(status) && mJARChannel->mJarCacheTransport) {
NS_ASSERTION(jarCacheTransport == (mJARChannel->mJarCacheTransport).get(),
"wrong transport");
@ -78,13 +108,16 @@ public:
rv = jarCacheFile->SetNotificationCallbacks(mJARChannel->mCallbacks);
if (NS_FAILED(rv)) return rv;
rv = mJARChannel->ExtractJARElement(jarCacheFile);
mJARChannel->SetJARBaseFile(jarCacheFile);
rv = mOnJARFileAvailable(mJARChannel, mClosure);
}
mJARChannel->mJarCacheTransport = nsnull;
return rv;
}
nsJARDownloadObserver(nsIFile* jarCacheFile, nsJARChannel* jarChannel) {
nsJARDownloadObserver(nsIFile* jarCacheFile, nsJARChannel* jarChannel,
OnJARFileAvailableFun onJARFileAvailable,
void* closure) {
NS_INIT_REFCNT();
mJarCacheFile = jarCacheFile;
mJARChannel = jarChannel;
@ -96,8 +129,10 @@ public:
}
protected:
nsCOMPtr<nsIFile> mJarCacheFile;
nsJARChannel* mJARChannel;
nsCOMPtr<nsIFile> mJarCacheFile;
nsJARChannel* mJARChannel;
OnJARFileAvailableFun mOnJARFileAvailable;
void* mClosure;
};
NS_IMPL_ISUPPORTS1(nsJARDownloadObserver, nsIStreamObserver)
@ -106,11 +141,24 @@ NS_IMPL_ISUPPORTS1(nsJARDownloadObserver, nsIStreamObserver)
nsJARChannel::nsJARChannel()
: mContentType(nsnull),
mContentLength(-1),
mStartPosition(0),
mReadCount(-1),
mJAREntry(nsnull),
mMonitor(nsnull),
mStatus(NS_OK)
{
NS_INIT_REFCNT();
#if defined(PR_LOGGING)
//
// Initialize the global PRLogModule for socket transport logging
// if necessary...
//
if (nsnull == gJarProtocolLog) {
gJarProtocolLog = PR_NewLogModule("nsJarProtocol");
}
#endif /* PR_LOGGING */
}
nsJARChannel::~nsJARChannel()
@ -270,11 +318,30 @@ nsJARChannel::SetURI(nsIURI* aURI)
return rv;
}
static nsresult
OpenJARElement(nsJARChannel* channel, void* closure)
{
nsresult rv;
nsIInputStream* *result = (nsIInputStream**)closure;
nsAutoCMonitor mon(channel);
rv = channel->Open(nsnull, nsnull);
if (NS_FAILED(rv)) return rv;
rv = channel->GetInputStream(result);
mon.Notify(); // wake up OpenInputStream
return rv;
}
NS_IMETHODIMP
nsJARChannel::OpenInputStream(nsIInputStream* *result)
{
NS_NOTREACHED("nsJARChannel::OpenInputStream");
return NS_ERROR_NOT_IMPLEMENTED;
nsAutoCMonitor mon(this);
nsresult rv;
*result = nsnull;
rv = EnsureJARFileAvailable(OpenJARElement, result);
if (NS_FAILED(rv)) return rv;
if (*result == nsnull)
mon.Wait();
return rv;
}
NS_IMETHODIMP
@ -291,10 +358,35 @@ nsJARChannel::AsyncOpen(nsIStreamObserver* observer, nsISupports* ctxt)
return NS_ERROR_NOT_IMPLEMENTED;
}
static nsresult
ReadJARElement(nsJARChannel* channel, void* closure)
{
nsresult rv;
rv = channel->AsyncReadJARElement();
return rv;
}
NS_IMETHODIMP
nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
{
mUserContext = ctxt;
mUserListener = listener;
return EnsureJARFileAvailable(ReadJARElement, nsnull);
}
nsresult
nsJARChannel::EnsureJARFileAvailable(OnJARFileAvailableFun onJARFileAvailable,
void* closure)
{
nsresult rv;
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: EnsureJARFileAvailable %s", (const char*)jarURLStr));
#endif
rv = mURI->GetJARFile(getter_AddRefs(mJARBaseURI));
if (NS_FAILED(rv)) return rv;
@ -315,14 +407,13 @@ nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
if (mLoadGroup)
(void)mLoadGroup->AddChannel(this, nsnull);
// XXX need to set a state variable here to say we're reading
mUserContext = ctxt;
mUserListener = listener;
mJARBaseFile = do_QueryInterface(jarBaseChannel, &rv);
nsCOMPtr<nsIFileChannel> jarBaseFile = do_QueryInterface(jarBaseChannel, &rv);
if (NS_SUCCEEDED(rv)) {
// then we've already got a local jar file -- no need to download it
rv = ExtractJARElement(jarBaseFile);
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: extracting local jar file %s", (const char*)jarURLStr));
rv = onJARFileAvailable(this, closure);
}
else {
// otherwise, we need to download the jar file
@ -338,18 +429,19 @@ nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
if (NS_SUCCEEDED(rv) && filePresent)
{
// then we've already got the file in the local cache -- no need to download it
nsCOMPtr<nsIFileChannel> fileChannel;
rv = NS_NewLocalFileChannel(getter_AddRefs(fileChannel),
rv = NS_NewLocalFileChannel(getter_AddRefs(mJARBaseFile),
jarCacheFile,
PR_RDONLY,
0);
if (NS_FAILED(rv)) return rv;
rv = fileChannel->SetBufferSegmentSize(mBufferSegmentSize);
rv = mJARBaseFile->SetBufferSegmentSize(mBufferSegmentSize);
if (NS_FAILED(rv)) return rv;
rv = fileChannel->SetBufferMaxSize(mBufferMaxSize);
rv = mJARBaseFile->SetBufferMaxSize(mBufferMaxSize);
if (NS_FAILED(rv)) return rv;
rv = ExtractJARElement(fileChannel);
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar file already in cache %s", (const char*)jarURLStr));
rv = onJARFileAvailable(this, closure);
return rv;
}
@ -372,10 +464,13 @@ nsJARChannel::AsyncRead(nsIStreamListener* listener, nsISupports* ctxt)
rv = mJarCacheTransport->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIStreamObserver> downloadObserver = new nsJARDownloadObserver(jarCacheFile, this);
nsCOMPtr<nsIStreamObserver> downloadObserver =
new nsJARDownloadObserver(jarCacheFile, this, onJARFileAvailable, closure);
if (downloadObserver == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: downloading jar file %s", (const char*)jarURLStr));
nsCOMPtr<nsIInputStream> jarBaseIn;
rv = jarBaseChannel->OpenInputStream(getter_AddRefs(jarBaseIn));
if (NS_FAILED(rv)) return rv;
@ -422,13 +517,32 @@ nsJARChannel::GetCacheFile(nsIFile* *cacheFile)
}
nsresult
nsJARChannel::ExtractJARElement(nsIFileChannel* jarBaseFile)
nsJARChannel::AsyncReadJARElement()
{
nsresult rv;
nsAutoMonitor monitor(mMonitor);
mJARBaseFile = jarBaseFile;
NS_ASSERTION(mJARBaseFile, "mJARBaseFile is null");
if (mLoadGroup) {
nsCOMPtr<nsILoadGroupListenerFactory> factory;
//
// Create a load group "proxy" listener...
//
rv = mLoadGroup->GetGroupListenerFactory(getter_AddRefs(factory));
if (factory) {
nsIStreamListener *newListener;
rv = factory->CreateLoadGroupListener(mUserListener, &newListener);
if (NS_SUCCEEDED(rv)) {
mUserListener = newListener;
NS_RELEASE(newListener);
}
}
rv = mLoadGroup->AddChannel(this, nsnull);
if (NS_FAILED(rv)) return rv;
}
NS_WITH_SERVICE(nsIFileTransportService, fts, kFileTransportServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
@ -444,6 +558,16 @@ nsJARChannel::ExtractJARElement(nsIFileChannel* jarBaseFile)
rv = mJarExtractionTransport->SetNotificationCallbacks(mCallbacks);
if (NS_FAILED(rv)) return rv;
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: AsyncRead jar entry %s", (const char*)jarURLStr));
#endif
rv = mJarExtractionTransport->SetTransferOffset(mStartPosition);
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->SetTransferCount(mReadCount);
if (NS_FAILED(rv)) return rv;
rv = mJarExtractionTransport->AsyncRead(this, nsnull);
return rv;
}
@ -723,10 +847,27 @@ nsJARChannel::OnStopRequest(nsIChannel* jarExtractionTransport,
const PRUnichar* aMsg)
{
nsresult rv;
#ifdef PR_LOGGING
nsCOMPtr<nsIURI> jarURI;
nsXPIDLCString jarURLStr;
rv = mURI->GetSpec(getter_Copies(jarURLStr));
if (NS_SUCCEEDED(rv)) {
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: jar extraction complete %s status=%x",
(const char*)jarURLStr, status));
}
#endif
rv = mUserListener->OnStopRequest(this, mUserContext, status, aMsg);
if (mLoadGroup) {
if (NS_SUCCEEDED(rv)) {
mLoadGroup->RemoveChannel(this, context, status, aMsg);
}
}
mUserListener = nsnull;
mUserContext = nsnull;
mJarExtractionTransport = nsnull;
if (mLoadGroup)
mLoadGroup->RemoveChannel(this, nsnull, rv, nsnull);
return rv;
}
@ -751,6 +892,8 @@ NS_IMETHODIMP
nsJARChannel::Open(char* *contentType, PRInt32 *contentLength)
{
nsresult rv;
NS_ASSERTION(mJARBaseFile, "mJARBaseFile is null");
rv = nsComponentManager::CreateInstance(kZipReaderCID,
nsnull,
NS_GET_IID(nsIZipReader),
@ -774,10 +917,16 @@ nsJARChannel::Open(char* *contentType, PRInt32 *contentLength)
rv = mJAR->GetEntry(mJAREntry, getter_AddRefs(entry));
if (NS_FAILED(rv)) return rv;
rv = entry->GetRealSize((PRUint32*)contentLength);
if (NS_FAILED(rv)) return rv;
if (contentLength) {
rv = entry->GetRealSize((PRUint32*)contentLength);
if (NS_FAILED(rv)) return rv;
}
return GetContentType(contentType);
if (contentType) {
rv = GetContentType(contentType);
if (NS_FAILED(rv)) return rv;
}
return rv;
}
@ -791,6 +940,12 @@ nsJARChannel::Close(nsresult status)
NS_IMETHODIMP
nsJARChannel::GetInputStream(nsIInputStream* *aInputStream)
{
#ifdef PR_LOGGING
nsXPIDLCString jarURLStr;
mURI->GetSpec(getter_Copies(jarURLStr));
PR_LOG(gJarProtocolLog, PR_LOG_DEBUG,
("nsJarProtocol: GetInputStream jar entry %s", (const char*)jarURLStr));
#endif
return mJAR->GetInputStream(mJAREntry, aInputStream);
}

View File

@ -38,6 +38,7 @@
#include "prmon.h"
class nsIFileChannel;
class nsJARChannel;
#define NS_JARCHANNEL_CID \
{ /* 0xc7e410d5-0x85f2-11d3-9f63-006008a6efe9 */ \
@ -49,6 +50,9 @@ class nsIFileChannel;
#define JAR_DIRECTORY "jarCache"
typedef nsresult
(*OnJARFileAvailableFun)(nsJARChannel* channel, void* closure);
class nsJARChannel : public nsIJARChannel,
public nsIStreamListener,
public nsIFileSystem
@ -70,9 +74,13 @@ public:
Create(nsISupports* aOuter, REFNSIID aIID, void **aResult);
nsresult Init(nsIJARProtocolHandler* aHandler, nsIURI* uri);
nsresult ExtractJARElement(nsIFileChannel* jarFileChannel);
nsresult EnsureJARFileAvailable(OnJARFileAvailableFun fun,
void* closure);
nsresult AsyncReadJARElement();
nsresult GetCacheFile(nsIFile* *cacheFile);
void SetJARBaseFile(nsIFileChannel* channel) { mJARBaseFile = channel; }
friend class nsJARDownloadObserver;
protected: