Mozilla/mozilla/network/module/nsNetStream.cpp
valeski%netscape.com a192f6bdd0 network/module/nsIRefreshUrl.h
Extended the nsIRefreshUrl interface to include a cancel method.

network/module/nsNetService.cpp
1. Added code to hook the nsConnectionInfo object up to the nsISupports pointer in the url being loaded.
2. Removed the redirect logic in bam_exit_routine(). The backend dependency on the front end is gone.

network/module/nsNetStream.cpp
Added initialization/destruction of the nsISupports pointer in the nsConnectionInfo.

network/module/nsNetStream.h
Added the nsISupports member declaration to nsConnectionInfo, and remvoed the redirect member variable.

network/module/nsNetStubs.cpp
FE_SetRefreshURLTimer() routine has been modified so it no longer relies on the pConsumer (i.e. nsDocumentBindInfo) which was causing us to leak it. Now we use the nsISupports pointer in the nsConnectionInfo object to access the nsIRefreshURL interface so we can reload the url.

network/module/nsStubContext.cpp
Modified stub_complete() so we no longer pay attention to the redirect member of the nsConnectionInfo object.

network/module/nsIURL.h
1. Added GetContainer() method to nsIURL which returns the nsISupports pointer of the container for this url.
2. created a new NS_NewURL() routine which takes an nsISupports pointer as a parameter.

network/module/nsURL.cpp
1. Added a new nsURL constructor that takes a nsISupports pointer as a param.
2. Added GetContainer() method and nsISupports pointer initialization/destruction.


git-svn-id: svn://10.0.0.236/trunk@8163 18797224-902f-48f8-a5cc-f745e15eee43
1998-08-18 23:24:28 +00:00

711 lines
16 KiB
C++

/* -*- 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsNetStream.h"
#include "net.h"
#include "mktrace.h"
/* XXX: Declare NET_PollSockets(...) for the blocking stream hack... */
extern "C" {
XP_Bool NET_PollSockets(void);
};
NS_DEFINE_IID(kIInputStreamIID, NS_IINPUTSTREAM_IID);
#define BUFFER_BLOCK_SIZE 8192
nsConnectionInfo::nsConnectionInfo(nsIURL *aURL,
nsNetlibStream *aStream,
nsIStreamListener *aNotify)
{
NS_INIT_REFCNT();
pURL = aURL;
pNetStream = aStream;
pConsumer = aNotify;
pContainer = nsnull;
if (NULL != pURL) {
pURL->AddRef();
}
if (NULL != pNetStream) {
pNetStream->AddRef();
}
if (NULL != pConsumer) {
pConsumer->AddRef();
}
}
NS_IMPL_ISUPPORTS(nsConnectionInfo,kISupportsIID);
nsConnectionInfo::~nsConnectionInfo()
{
TRACEMSG(("nsConnectionInfo is being destroyed...\n"));
if (NULL != pURL) {
pURL->Release();
}
if (NULL != pNetStream) {
pNetStream->Close();
pNetStream->Release();
}
if (NULL != pConsumer) {
pConsumer->Release();
}
if (nsnull != pContainer) {
NS_RELEASE(pContainer);
}
pURL = NULL;
pNetStream = NULL;
pConsumer = NULL;
pContainer = nsnull;
}
nsNetlibStream::nsNetlibStream(void)
{
NS_INIT_REFCNT();
m_Lock = PR_NewMonitor();
m_bIsClosed = PR_FALSE;
}
NS_IMPL_ADDREF(nsNetlibStream)
NS_IMPL_RELEASE(nsNetlibStream)
nsresult nsNetlibStream::QueryInterface(const nsIID &aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIInputStreamIID, NS_IINPUTSTREAM_IID);
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
if (aIID.Equals(kIInputStreamIID)) {
*aInstancePtr = (void*) ((nsIInputStream*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kIOutputStreamIID)) {
*aInstancePtr = (void*) ((nsIOutputStream*)this);
AddRef();
return NS_OK;
}
if (aIID.Equals(kISupportsIID)) {
*aInstancePtr = ((nsISupports *)(nsIInputStream *)this);
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
nsNetlibStream::~nsNetlibStream()
{
if (m_Lock) {
PR_DestroyMonitor(m_Lock);
m_Lock = NULL;
}
}
nsresult nsNetlibStream::Close()
{
LockStream();
m_bIsClosed = PR_TRUE;
UnlockStream();
return NS_OK;
}
nsBufferedStream::nsBufferedStream(void)
{
m_BufferLength = BUFFER_BLOCK_SIZE;
m_Buffer = new char[m_BufferLength];
/* If the allocation failed, mark the stream as closed... */
if (NULL == m_Buffer) {
m_bIsClosed = PR_TRUE;
m_BufferLength = 0;
}
m_DataLength = 0;
m_ReadOffset = m_WriteOffset = 0;
}
nsBufferedStream::~nsBufferedStream()
{
TRACEMSG(("nsBufferedStream is being destroyed...\n"));
if (m_Buffer) {
free(m_Buffer);
m_Buffer = NULL;
}
}
PRInt32 nsBufferedStream::GetAvailableSpace(PRInt32 *aErrorCode)
{
PRInt32 size = 0;
if (m_bIsClosed) {
*aErrorCode = NS_BASE_STREAM_EOF;
} else {
*aErrorCode = NS_OK;
LockStream();
size = m_BufferLength - m_WriteOffset;
UnlockStream();
}
return size;
}
nsresult nsBufferedStream::GetLength(PRInt32 *aLength)
{
LockStream();
*aLength = m_WriteOffset;
UnlockStream();
return NS_OK;
}
nsresult nsBufferedStream::Write(const char *aBuf,
PRInt32 aOffset,
PRInt32 aLen,
PRInt32 *aWriteCount)
{
PRInt32 bytesFree;
nsresult rv = NS_OK;
LockStream();
NS_PRECONDITION((m_Buffer || m_bIsClosed), "m_Buffer is NULL!");
NS_PRECONDITION((m_WriteOffset >= m_ReadOffset), "Read past the end of buffer.");
/* Check for initial error conditions... */
if (NULL == aBuf) {
rv = NS_BASE_STREAM_ILLEGAL_ARGS;
goto done;
} else if (m_bIsClosed) {
rv = NS_BASE_STREAM_EOF;
goto done;
}
if (!m_bIsClosed && aBuf) {
/* Grow the buffer if necessary */
bytesFree = m_BufferLength - m_WriteOffset;
if (aLen > bytesFree) {
char *newBuffer;
m_BufferLength += (((aLen - bytesFree) / BUFFER_BLOCK_SIZE)+1) * BUFFER_BLOCK_SIZE;
newBuffer = (char *)realloc(m_Buffer, m_BufferLength);
/* If the allocation failed, close the stream and free the buffer... */
if (NULL == newBuffer) {
m_bIsClosed = PR_TRUE;
free(m_Buffer);
m_Buffer = NULL;
m_BufferLength = 0;
goto done;
} else {
m_Buffer = newBuffer;
}
}
/* Skip the appropriate number of bytes in the input buffer... */
if (aOffset) {
aBuf += aOffset;
}
memcpy(&m_Buffer[m_WriteOffset], aBuf, aLen);
m_WriteOffset += aLen;
*aWriteCount = aLen;
m_DataLength += aLen;
}
done:
UnlockStream();
return rv;
}
nsresult nsBufferedStream::Read(char *aBuf,
PRInt32 aOffset,
PRInt32 aCount,
PRInt32 *aReadCount)
{
nsresult rv = NS_OK;
LockStream();
NS_PRECONDITION((m_Buffer || m_bIsClosed), "m_Buffer is NULL!");
NS_PRECONDITION((m_WriteOffset >= m_ReadOffset), "Read past the end of buffer.");
/* Check for initial error conditions... */
if (NULL == aBuf) {
rv = NS_BASE_STREAM_ILLEGAL_ARGS;
*aReadCount = 0;
goto done;
} else if (m_bIsClosed && (0 == m_DataLength)) {
rv = NS_BASE_STREAM_EOF;
*aReadCount = 0;
goto done;
}
if (m_Buffer && m_DataLength) {
/* Skip the appropriate number of bytes in the input buffer... */
if (aOffset) {
aBuf += aOffset;
}
/* Do not read more data than there is available... */
if (aCount > m_DataLength) {
aCount = m_DataLength;
}
memcpy(aBuf, &m_Buffer[m_ReadOffset], aCount);
m_ReadOffset += aCount;
*aReadCount = aCount;
m_DataLength -= aCount;
}
else
*aReadCount = 0;
done:
UnlockStream();
return rv;
}
nsAsyncStream::nsAsyncStream(PRInt32 buffer_size)
{
m_BufferLength = buffer_size;
m_Buffer = (char *)malloc(m_BufferLength);
/* If the allocation failed, mark the stream as closed... */
if (NULL == m_Buffer) {
m_bIsClosed = PR_TRUE;
m_BufferLength = 0;
}
m_DataLength = 0;
m_ReadOffset = m_WriteOffset = 0;
}
nsAsyncStream::~nsAsyncStream()
{
TRACEMSG(("nsAsyncStream is being destroyed...\n"));
if (m_Buffer) {
free(m_Buffer);
m_Buffer = NULL;
}
}
PRInt32 nsAsyncStream::GetAvailableSpace(PRInt32 *aErrorCode)
{
PRInt32 size = 0;
if (m_bIsClosed) {
*aErrorCode = NS_BASE_STREAM_EOF;
} else {
*aErrorCode = NS_OK;
LockStream();
size = m_BufferLength - m_DataLength;
UnlockStream();
}
return size;
}
nsresult nsAsyncStream::GetLength(PRInt32 *aLength)
{
LockStream();
*aLength = m_DataLength;
UnlockStream();
return NS_OK;
}
nsresult nsAsyncStream::Write(const char *aBuf,
PRInt32 aOffset,
PRInt32 aLen,
PRInt32 *aWriteCount)
{
PRInt32 bytesFree;
nsresult rv = NS_OK;
LockStream();
NS_PRECONDITION((m_Buffer || m_bIsClosed), "m_Buffer is NULL!");
/* Check for initial error conditions... */
if (NULL == aBuf) {
rv = NS_BASE_STREAM_ILLEGAL_ARGS;
goto done;
} else if (m_bIsClosed) {
rv = NS_BASE_STREAM_EOF;
goto done;
}
if (!m_bIsClosed && aBuf) {
/* Skip the appropriate number of bytes in the input buffer... */
if (aOffset) {
aBuf += aOffset;
}
/* Do not store more data than there is space for... */
bytesFree = m_BufferLength - m_DataLength;
if (aLen > bytesFree) {
aLen = bytesFree;
}
/* Storing the data will cause m_WriteOffset to wrap */
if (m_WriteOffset + aLen > m_BufferLength) {
PRInt32 delta;
/* Store the first chunk through the end of the buffer */
delta = m_BufferLength - m_WriteOffset;
memcpy(&m_Buffer[m_WriteOffset], aBuf, delta);
/* Store the second chunk from the beginning of the buffer */
m_WriteOffset = aLen-delta;
memcpy(m_Buffer, &aBuf[delta], m_WriteOffset);
} else {
memcpy(&m_Buffer[m_WriteOffset], aBuf, aLen);
m_WriteOffset += aLen;
}
*aWriteCount = aLen;
m_DataLength += aLen;
}
done:
UnlockStream();
return rv;
}
nsresult nsAsyncStream::Read(char *aBuf,
PRInt32 aOffset,
PRInt32 aCount,
PRInt32 *aReadCount)
{
nsresult rv = NS_OK;
LockStream();
NS_PRECONDITION((m_Buffer || m_bIsClosed), "m_Buffer is NULL!");
/* Check for initial error conditions... */
if (NULL == aBuf) {
rv = NS_BASE_STREAM_ILLEGAL_ARGS;
*aReadCount = 0;
goto done;
} else if (m_bIsClosed && (0 == m_DataLength)) {
rv = NS_BASE_STREAM_EOF;
*aReadCount = 0;
goto done;
}
if (m_Buffer && m_DataLength) {
/* Skip the appropriate number of bytes in the input buffer... */
if (aOffset) {
aBuf += aOffset;
}
/* Do not read more data than there is available... */
if (aCount > m_DataLength) {
aCount = m_DataLength;
}
/* Reading the data will cause m_ReadOffset to wrap */
if (m_ReadOffset + aCount > m_BufferLength) {
PRInt32 delta;
/* Read the first chunk through the end of the buffer */
delta = m_BufferLength - m_ReadOffset;
memcpy(aBuf, &m_Buffer[m_ReadOffset], delta);
/* Read the second chunk from the beginning of the buffer */
m_ReadOffset = aCount-delta;
memcpy(&aBuf[delta], m_Buffer, m_ReadOffset);
} else {
memcpy(aBuf, &m_Buffer[m_ReadOffset], aCount);
m_ReadOffset += aCount;
}
*aReadCount = aCount;
m_DataLength -= aCount;
}
else
*aReadCount = 0;
done:
UnlockStream();
return rv;
}
nsBlockingStream::nsBlockingStream()
{
m_BufferLength = BUFFER_BLOCK_SIZE;
m_Buffer = (char *)malloc(m_BufferLength);
/* If the allocation failed, mark the stream as closed... */
if (NULL == m_Buffer) {
m_bIsClosed = PR_TRUE;
m_BufferLength = 0;
}
m_DataLength = 0;
m_ReadOffset = m_WriteOffset = 0;
}
nsBlockingStream::~nsBlockingStream()
{
TRACEMSG(("nsBlockingStream is being destroyed...\n"));
if (m_Buffer) {
free(m_Buffer);
m_Buffer = NULL;
}
}
PRInt32 nsBlockingStream::GetAvailableSpace(PRInt32 *aErrorCode)
{
PRInt32 size = 0;
if (m_bIsClosed) {
*aErrorCode = NS_BASE_STREAM_EOF;
} else {
*aErrorCode = NS_OK;
LockStream();
size = m_BufferLength - m_DataLength;
UnlockStream();
}
return size;
}
nsresult nsBlockingStream::GetLength(PRInt32 *aLength)
{
LockStream();
*aLength = m_DataLength;
UnlockStream();
return NS_OK;
}
nsresult nsBlockingStream::Write(const char *aBuf,
PRInt32 aOffset,
PRInt32 aLen,
PRInt32 *aWriteCount)
{
PRInt32 bytesFree;
nsresult rv = NS_OK;
LockStream();
NS_PRECONDITION((m_Buffer || m_bIsClosed), "m_Buffer is NULL!");
/* Check for initial error conditions... */
if (NULL == aBuf) {
rv = NS_BASE_STREAM_ILLEGAL_ARGS;
goto done;
} else if (m_bIsClosed) {
rv = NS_BASE_STREAM_EOF;
goto done;
}
if (!m_bIsClosed && aBuf) {
/* Skip the appropriate number of bytes in the input buffer... */
if (aOffset) {
aBuf += aOffset;
}
/* Do not store more data than there is space for... */
bytesFree = m_BufferLength - m_DataLength;
if (aLen > bytesFree) {
aLen = bytesFree;
}
/* Storing the data will cause m_WriteOffset to wrap */
if (m_WriteOffset + aLen > m_BufferLength) {
PRInt32 delta;
/* Store the first chunk through the end of the buffer */
delta = m_BufferLength - m_WriteOffset;
memcpy(&m_Buffer[m_WriteOffset], aBuf, delta);
/* Store the second chunk from the beginning of the buffer */
m_WriteOffset = aLen-delta;
memcpy(m_Buffer, &aBuf[delta], m_WriteOffset);
} else {
memcpy(&m_Buffer[m_WriteOffset], aBuf, aLen);
m_WriteOffset += aLen;
}
*aWriteCount = aLen;
m_DataLength += aLen;
}
done:
UnlockStream();
return rv;
}
nsresult nsBlockingStream::Read(char *aBuf,
PRInt32 aOffset,
PRInt32 aCount,
PRInt32 *aReadCount)
{
nsresult rv = NS_OK;
LockStream();
*aReadCount = 0;
NS_PRECONDITION((m_Buffer || m_bIsClosed), "m_Buffer is NULL!");
/* Check for initial error conditions... */
if (NULL == aBuf) {
rv = NS_BASE_STREAM_ILLEGAL_ARGS;
goto done;
} else if (m_bIsClosed && (0 == m_DataLength)) {
rv = NS_BASE_STREAM_EOF;
goto done;
}
if (m_Buffer) {
/* Skip the appropriate number of bytes in the input buffer... */
if (aOffset) {
aBuf += aOffset;
}
/* Not enough data is available... Must block. */
if (aCount > m_DataLength) {
UnlockStream();
do {
NET_PollSockets();
*aReadCount += ReadBuffer(aBuf + *aReadCount, aCount - *aReadCount);
/* XXX m_bIsClosed is checked outside of the lock! */
} while ((aCount > *aReadCount) && !m_bIsClosed);
LockStream();
/*
* It is possible that the stream was closed during
* NET_PollSockets(...)... In this case, return EOF if no data
* is available...
*/
if ((0 == *aReadCount) && m_bIsClosed) {
rv = NS_BASE_STREAM_EOF;
}
} else {
*aReadCount = ReadBuffer(aBuf, aCount);
}
}
done:
UnlockStream();
return rv;
}
PRInt32 nsBlockingStream::ReadBuffer(char *aBuf, PRInt32 aCount)
{
PRInt32 bytesRead = 0;
LockStream();
/* Do not read more data than there is available... */
if (aCount > m_DataLength) {
aCount = m_DataLength;
}
/* Reading the data will cause m_ReadOffset to wrap */
if (m_ReadOffset + aCount > m_BufferLength) {
PRInt32 delta;
/* Read the first chunk through the end of the buffer */
delta = m_BufferLength - m_ReadOffset;
memcpy(aBuf, &m_Buffer[m_ReadOffset], delta);
/* Read the second chunk from the beginning of the buffer */
m_ReadOffset = aCount-delta;
memcpy(&aBuf[delta], m_Buffer, m_ReadOffset);
} else {
memcpy(aBuf, &m_Buffer[m_ReadOffset], aCount);
m_ReadOffset += aCount;
}
bytesRead = aCount;
m_DataLength -= aCount;
UnlockStream();
return bytesRead;
}