Removed file transport, now consolidated with file channel. Various buffer(stream) cleanup.

This commit is contained in:
warren%netscape.com 1999-06-15 05:18:40 +00:00
parent d92e35fc40
commit f44c21a640
22 changed files with 395 additions and 204 deletions

View File

@ -30,6 +30,7 @@ interface nsIStreamObserver;
interface nsIStreamListener;
interface nsIEventQueue;
interface nsIBufferInputStream;
interface nsIBufferOutputStream;
[scriptable, uuid(01f0a170-1881-11d3-9337-00104ba0fd40)]
interface nsIIOService : nsISupports
@ -124,7 +125,8 @@ interface nsIIOService : nsISupports
* A synchronous stream listener pushes data through a pipe that ends up
* in an input stream to be read by another thread.
*/
nsIStreamListener NewSyncStreamListener(out nsIBufferInputStream inStream);
nsIStreamListener NewSyncStreamListener(out nsIBufferInputStream inStream,
out nsIBufferOutputStream outStream);
};

View File

@ -19,6 +19,7 @@
#include "nsIStreamObserver.idl"
interface nsIBufferInputStream;
interface nsIBufferOutputStream;
interface nsIEventQueue;
[scriptable, uuid(1a637020-1482-11d3-9333-00104ba0fd40)]
@ -43,7 +44,8 @@ NS_NewAsyncStreamListener(nsIStreamListener* *result,
// A synchronous stream listener pushes data through a pipe that ends up
// in an input stream to be read by another thread.
extern NS_NET nsresult
NS_NewSyncStreamListener(nsIStreamListener* *listener,
nsIBufferInputStream* *inStream);
NS_NewSyncStreamListener(nsIBufferInputStream **inStream,
nsIBufferOutputStream **outStream,
nsIStreamListener **listener);
%}

View File

@ -29,8 +29,6 @@ CPPSRCS = \
nsAsyncStreamListener.cpp \
nsSyncStreamListener.cpp \
nsIOService.cpp \
nsFileTransport.cpp \
nsFileTransportService.cpp \
nsSocketTransport.cpp \
nsSocketTransportStreams.cpp \
nsSocketTransportService.cpp \

View File

@ -31,8 +31,6 @@ CPP_OBJS = \
.\$(OBJDIR)\nsAsyncStreamListener.obj \
.\$(OBJDIR)\nsSyncStreamListener.obj \
.\$(OBJDIR)\nsIOService.obj \
.\$(OBJDIR)\nsFileTransport.obj \
.\$(OBJDIR)\nsFileTransportService.obj \
.\$(OBJDIR)\nsSocketTransport.obj \
.\$(OBJDIR)\nsSocketTransportStreams.obj \
.\$(OBJDIR)\nsSocketTransportService.obj \

View File

@ -40,18 +40,18 @@ public:
// nsAsyncStreamObserver methods:
nsAsyncStreamObserver(nsIEventQueue* aEventQ)
: mReceiver(nsnull), mStatus(NS_OK)
: mReceiver(nsnull), mStatus(NS_OK)
{
NS_INIT_REFCNT();
mEventQueue = aEventQ;
NS_IF_ADDREF(mEventQueue);
NS_INIT_REFCNT();
mEventQueue = aEventQ;
NS_IF_ADDREF(mEventQueue);
}
virtual ~nsAsyncStreamObserver();
void Init(nsIStreamObserver* aListener) {
mReceiver = aListener;
NS_ADDREF(mReceiver);
mReceiver = aListener;
NS_ADDREF(mReceiver);
}
nsISupports* GetReceiver() { return mReceiver; }
@ -74,26 +74,26 @@ public:
// nsIStreamListener methods:
NS_IMETHOD OnStartBinding(nsISupports* context)
{
return nsAsyncStreamObserver::OnStartBinding(context);
return nsAsyncStreamObserver::OnStartBinding(context);
}
NS_IMETHOD OnStopBinding(nsISupports* context,
nsresult aStatus,
const PRUnichar* aMsg)
{
return nsAsyncStreamObserver::OnStopBinding(context, aStatus, aMsg);
return nsAsyncStreamObserver::OnStopBinding(context, aStatus, aMsg);
}
NS_IMETHOD OnStartRequest(nsISupports* context)
{
return nsAsyncStreamObserver::OnStartRequest(context);
return nsAsyncStreamObserver::OnStartRequest(context);
}
NS_IMETHOD OnStopRequest(nsISupports* context,
nsresult aStatus,
const PRUnichar* aMsg)
{
return nsAsyncStreamObserver::OnStopRequest(context, aStatus, aMsg);
return nsAsyncStreamObserver::OnStopRequest(context, aStatus, aMsg);
}
NS_IMETHOD OnDataAvailable(nsISupports* context,
@ -103,11 +103,11 @@ public:
// nsAsyncStreamListener methods:
nsAsyncStreamListener(nsIEventQueue* aEventQ)
: nsAsyncStreamObserver(aEventQ) {}
: nsAsyncStreamObserver(aEventQ) {}
void Init(nsIStreamListener* aListener) {
mReceiver = aListener;
NS_ADDREF(mReceiver);
mReceiver = aListener;
NS_ADDREF(mReceiver);
}
};
@ -128,8 +128,8 @@ protected:
static void PR_CALLBACK HandlePLEvent(PLEvent* aEvent);
static void PR_CALLBACK DestroyPLEvent(PLEvent* aEvent);
nsAsyncStreamObserver* mListener;
nsISupports* mContext;
nsAsyncStreamObserver* mListener;
nsISupports* mContext;
};
////////////////////////////////////////////////////////////////////////////////

View File

@ -284,10 +284,11 @@ nsIOService::NewAsyncStreamListener(nsIStreamListener *receiver, nsIEventQueue *
}
NS_IMETHODIMP
nsIOService:: NewSyncStreamListener(nsIBufferInputStream **inStream,
nsIStreamListener **listener)
nsIOService::NewSyncStreamListener(nsIBufferInputStream **inStream,
nsIBufferOutputStream **outStream,
nsIStreamListener **listener)
{
return NS_NewSyncStreamListener(listener, inStream);
return NS_NewSyncStreamListener(inStream, outStream, listener);
}

View File

@ -50,7 +50,7 @@ public:
NS_IMETHOD GetUserAgent(PRUnichar* *aUserAgent);
NS_IMETHOD NewAsyncStreamObserver(nsIStreamObserver *receiver, nsIEventQueue *eventQueue, nsIStreamObserver **_retval);
NS_IMETHOD NewAsyncStreamListener(nsIStreamListener *receiver, nsIEventQueue *eventQueue, nsIStreamListener **_retval);
NS_IMETHOD NewSyncStreamListener(nsIBufferInputStream **inStream, nsIStreamListener **_retval);
NS_IMETHOD NewSyncStreamListener(nsIBufferInputStream **inStream, nsIBufferOutputStream **outStream, nsIStreamListener **_retval);
// nsIOService methods:
nsIOService();

View File

@ -1131,8 +1131,8 @@ nsSocketTransport::OpenOutputStream(PRUint32 startPosition, nsIOutputStream* *re
// XXX not sure if this should be blocking (PR_TRUE) or non-blocking.
nsIBufferOutputStream* out = nsnull;
rv = NS_NewPipe2(&mWriteStream, &out,
MAX_IO_BUFFER_SIZE, MAX_IO_BUFFER_SIZE);
rv = NS_NewPipe(&mWriteStream, &out,
MAX_IO_BUFFER_SIZE, MAX_IO_BUFFER_SIZE, PR_TRUE, nsnull);
*result = out;
}

View File

@ -105,7 +105,7 @@ nsresult nsSocketTransportStream::Init(nsSocketTransport* aTransport,
}
if (NS_SUCCEEDED(rv)) {
rv = NS_NewBuffer(&mBuffer, MAX_IO_BUFFER_SIZE/2, 2*MAX_IO_BUFFER_SIZE);
rv = NS_NewBuffer(&mBuffer, MAX_IO_BUFFER_SIZE/2, 2*MAX_IO_BUFFER_SIZE, nsnull);
}
if (NS_SUCCEEDED(rv)) {
rv = NS_NewBufferInputStream(&mStream, mBuffer);

View File

@ -54,19 +54,25 @@ public:
nsresult Init(nsIBufferInputStream* *result);
nsIBufferOutputStream* GetOutputStream() { return mOutputStream; }
protected:
nsIBufferOutputStream* mOutputStream;
};
////////////////////////////////////////////////////////////////////////////////
#define NS_SYNC_STREAM_LISTENER_SEGMENT_SIZE (4 * 1024)
#define NS_SYNC_STREAM_LISTENER_BUFFER_SIZE (32 * 1024)
nsresult
nsSyncStreamListener::Init(nsIBufferInputStream* *result)
{
nsresult rv;
nsIBufferInputStream* in;
rv = NS_NewPipe2(&in, &mOutputStream, 4 * 1024, 16 * 1024);
rv = NS_NewPipe(&in, &mOutputStream, NS_SYNC_STREAM_LISTENER_SEGMENT_SIZE,
NS_SYNC_STREAM_LISTENER_BUFFER_SIZE, PR_TRUE, nsnull);
if (NS_FAILED(rv)) return rv;
*result = in;
@ -145,8 +151,9 @@ nsSyncStreamListener::OnDataAvailable(nsISupports* context,
////////////////////////////////////////////////////////////////////////////////
NS_NET nsresult
NS_NewSyncStreamListener(nsIStreamListener* *listener,
nsIBufferInputStream* *inStream)
NS_NewSyncStreamListener(nsIBufferInputStream **inStream,
nsIBufferOutputStream **outStream,
nsIStreamListener **listener)
{
nsSyncStreamListener* l = new nsSyncStreamListener();
if (l == nsnull)
@ -160,6 +167,7 @@ NS_NewSyncStreamListener(nsIStreamListener* *listener,
NS_ADDREF(l);
*listener = l;
*outStream = l->GetOutputStream();
return NS_OK;
}

View File

@ -21,7 +21,7 @@
#include "nsIServiceManager.h"
#include "nsIOService.h"
#include "nsNetModuleMgr.h"
#include "nsFileTransportService.h"
//#include "nsFileTransportService.h"
#include "nsSocketTransportService.h"
#include "nscore.h"
#include "nsStandardUrl.h"
@ -29,7 +29,7 @@
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
//static NS_DEFINE_CID(kFileTransportServiceCID, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kStandardURLCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kSocketTransportServiceCID, NS_SOCKETTRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kExternalModuleManagerCID, NS_NETMODULEMGR_CID);
@ -52,9 +52,11 @@ NSGetFactory(nsISupports* aServMgr,
if (aClass.Equals(kIOServiceCID)) {
rv = NS_NewGenericFactory(&fact, nsIOService::Create);
}
#if 0
else if (aClass.Equals(kFileTransportServiceCID)) {
rv = NS_NewGenericFactory(&fact, nsFileTransportService::Create);
}
#endif
else if (aClass.Equals(kSocketTransportServiceCID)) {
rv = NS_NewGenericFactory(&fact, nsSocketTransportService::Create);
}
@ -89,13 +91,13 @@ NSRegisterSelf(nsISupports* aServMgr , const char* aPath)
"component://netscape/network/net-service",
aPath, PR_TRUE, PR_TRUE);
if (NS_FAILED(rv)) return rv;
#if 0
rv = compMgr->RegisterComponent(kFileTransportServiceCID,
"File Transport Service",
"component://netscape/network/file-transport-service",
aPath, PR_TRUE, PR_TRUE);
if (NS_FAILED(rv)) return rv;
#endif
rv = compMgr->RegisterComponent(kSocketTransportServiceCID,
"Socket Transport Service",
"component://netscape/network/socket-transport-service",
@ -125,10 +127,10 @@ NSUnregisterSelf(nsISupports* aServMgr, const char* aPath)
rv = compMgr->UnregisterComponent(kIOServiceCID, aPath);
if (NS_FAILED(rv)) return rv;
#if 0
rv = compMgr->UnregisterComponent(kFileTransportServiceCID, aPath);
if (NS_FAILED(rv)) return rv;
#endif
rv = compMgr->UnregisterComponent(kSocketTransportServiceCID, aPath);
if (NS_FAILED(rv)) return rv;

View File

@ -42,28 +42,35 @@ NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
nsFileChannel::nsFileChannel()
: mURI(nsnull), mGetter(nsnull), mListener(nsnull), mEventQueue(nsnull),
mContext(nsnull), mState(ENDED),
mSuspended(PR_FALSE), mFileStream(nsnull), mBuffer(nsnull),
mBufferStream(nsnull), mStatus(NS_OK), mHandler(nsnull), mSourceOffset(0)
mContext(nsnull), mState(QUIESCENT),
mSuspended(PR_FALSE), mFileStream(nsnull),
mBufferInputStream(nsnull), mBufferOutputStream(nsnull),
mStatus(NS_OK), mHandler(nsnull), mSourceOffset(0)
{
NS_INIT_REFCNT();
}
nsresult
nsFileChannel::Init(const char* verb, nsIURI* uri, nsIEventSinkGetter* getter,
nsFileChannel::Init(nsFileProtocolHandler* handler,
const char* verb, nsIURI* uri, nsIEventSinkGetter* getter,
nsIEventQueue* queue)
{
nsresult rv;
mHandler = handler;
NS_ADDREF(mHandler);
mGetter = getter;
NS_ADDREF(mGetter);
NS_IF_ADDREF(mGetter);
mLock = PR_NewLock();
if (mLock == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
rv = getter->GetEventSink(verb, nsIStreamListener::GetIID(), (nsISupports**)&mListener);
if (NS_FAILED(rv)) return rv;
if (getter) {
rv = getter->GetEventSink(verb, nsIStreamListener::GetIID(), (nsISupports**)&mListener);
if (NS_FAILED(rv)) return rv;
}
mURI = uri;
NS_ADDREF(mURI);
@ -77,7 +84,7 @@ nsFileChannel::Init(const char* verb, nsIURI* uri, nsIEventSinkGetter* getter,
mSpec = fileURL;
mEventQueue = queue;
NS_ADDREF(mEventQueue);
NS_IF_ADDREF(mEventQueue);
return NS_OK;
}
@ -90,9 +97,9 @@ nsFileChannel::~nsFileChannel()
NS_IF_RELEASE(mEventQueue);
NS_IF_RELEASE(mContext);
NS_IF_RELEASE(mHandler);
NS_IF_RELEASE(mFileStream);
NS_IF_RELEASE(mBuffer);
NS_IF_RELEASE(mBufferStream);
NS_ASSERTION(mFileStream == nsnull, "channel not closed");
NS_ASSERTION(mBufferInputStream == nsnull, "channel not closed");
NS_ASSERTION(mBufferOutputStream == nsnull, "channel not closed");
if (mLock)
PR_DestroyLock(mLock);
}
@ -172,6 +179,104 @@ nsFileChannel::Resume()
return rv;
}
////////////////////////////////////////////////////////////////////////////////
class nsAsyncOutputStream : public nsIBufferOutputStream {
public:
NS_DECL_ISUPPORTS
// nsIBaseStream methods:
NS_IMETHOD Close() {
return mOutputStream->Close();
}
// nsIOutputStream methods:
NS_IMETHOD Write(const char *buf, PRUint32 count, PRUint32 *writeCount) {
nsresult rv;
rv = mOutputStream->Write(buf, count, writeCount);
if (NS_FAILED(rv)) return rv;
rv = mListener->OnDataAvailable(mContext, mInputStream, mOffset, *writeCount);
mOffset += *writeCount;
return rv;
}
NS_IMETHOD Flush() {
return mOutputStream->Flush();
}
// nsIBufferOutputStream methods:
NS_IMETHOD GetBuffer(nsIBuffer * *aBuffer) {
return mOutputStream->GetBuffer(aBuffer);
}
NS_IMETHOD WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *writeCount) {
nsresult rv;
rv = mOutputStream->WriteFrom(inStr, count, writeCount);
if (NS_FAILED(rv)) return rv;
rv = mListener->OnDataAvailable(mContext, mInputStream, mOffset, *writeCount);
mOffset += *writeCount;
return rv;
}
nsAsyncOutputStream()
: mContext(nsnull), mListener(nsnull), mInputStream(nsnull),
mOutputStream(nsnull), mOffset(0)
{
NS_INIT_REFCNT();
}
nsresult Init(nsISupports* context, nsIStreamListener* listener,
PRUint32 growBySize, PRUint32 maxSize) {
nsresult rv;
rv = NS_NewPipe(&mInputStream, &mOutputStream,
growBySize, maxSize, PR_TRUE, nsnull);
if (NS_FAILED(rv)) return rv;
mContext = context;
NS_IF_ADDREF(mContext);
mListener = listener;
NS_ADDREF(mListener);
return rv;
}
virtual ~nsAsyncOutputStream() {
NS_IF_RELEASE(mContext);
NS_IF_RELEASE(mListener);
NS_IF_RELEASE(mInputStream);
NS_IF_RELEASE(mOutputStream);
}
static NS_METHOD Create(nsIBufferInputStream* *inStr,
nsIBufferOutputStream* *outStr,
nsISupports* context, nsIStreamListener* listener,
PRUint32 growBySize, PRUint32 maxSize) {
nsAsyncOutputStream* str = new nsAsyncOutputStream();
if (str == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(str);
nsresult rv = str->Init(context, listener, growBySize, maxSize);
if (NS_FAILED(rv)) {
NS_RELEASE(str);
return rv;
}
*inStr = str->mInputStream;
*outStr = str;
return NS_OK;
}
protected:
nsISupports* mContext;
nsIStreamListener* mListener;
nsIBufferInputStream* mInputStream;
nsIBufferOutputStream* mOutputStream;
PRUint32 mOffset;
};
NS_IMPL_ISUPPORTS(nsAsyncOutputStream, nsIBufferOutputStream::GetIID());
////////////////////////////////////////////////////////////////////////////////
// From nsIChannel
////////////////////////////////////////////////////////////////////////////////
@ -192,18 +297,53 @@ nsFileChannel::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
nsresult rv;
if (mState != ENDED)
if (mState != QUIESCENT)
return NS_ERROR_IN_PROGRESS;
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = NS_NewPipe(&mBufferInputStream, &mBufferOutputStream,
NS_FILE_TRANSPORT_SEGMENT_SIZE,
NS_FILE_TRANSPORT_BUFFER_SIZE, PR_TRUE, nsnull);
// rv = serv->NewSyncStreamListener(&mBufferInputStream, &mBufferOutputStream, &mListener);
if (NS_FAILED(rv)) return rv;
mState = START_READ;
mSourceOffset = startPosition;
mAmount = readCount;
mListener = nsnull;
rv = mHandler->DispatchRequest(this);
if (NS_FAILED(rv)) return rv;
*result = mBufferInputStream;
NS_ADDREF(*result);
return NS_OK;
}
NS_IMETHODIMP
nsFileChannel::OpenOutputStream(PRUint32 startPosition, nsIOutputStream **result)
{
nsAutoLock lock(mLock);
nsresult rv;
if (mState != QUIESCENT)
return NS_ERROR_IN_PROGRESS;
#if 0
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsIStreamListener* syncListener;
nsIBufferInputStream* inStr;
rv = serv->NewSyncStreamListener(&inStr, &syncListener);
nsIBufferOutputStream* outStr;
rv = serv->NewSyncStreamListener(&inStr, &outStr, &syncListener);
if (NS_FAILED(rv)) return rv;
mListener = syncListener;
mOutputStream = outStr;
mState = START_READ;
mSourceOffset = startPosition;
mAmount = readCount;
@ -215,17 +355,19 @@ nsFileChannel::OpenInputStream(PRUint32 startPosition, PRInt32 readCount,
}
*result = inStr;
#else
NS_ASSERTION(startPosition == 0, "implement startPosition");
nsISupports* str;
rv = NS_NewTypicalOutputFileStream(&str, mSpec);
if (NS_FAILED(rv)) return rv;
rv = str->QueryInterface(nsIOutputStream::GetIID(), (void**)result);
NS_RELEASE(str);
return rv;
#endif
return NS_OK;
}
NS_IMETHODIMP
nsFileChannel::OpenOutputStream(PRUint32 startPosition, nsIOutputStream **_retval)
{
nsAutoLock lock(mLock);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsFileChannel::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
nsISupports *ctxt,
@ -239,11 +381,15 @@ nsFileChannel::AsyncRead(PRUint32 startPosition, PRInt32 readCount,
NS_WITH_SERVICE(nsIIOService, serv, kIOServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsIStreamListener* asyncListener;
rv = serv->NewAsyncStreamListener(listener, eventQueue, &asyncListener);
rv = serv->NewAsyncStreamListener(listener, eventQueue, &mListener);
if (NS_FAILED(rv)) return rv;
mListener = asyncListener;
rv = nsAsyncOutputStream::Create(&mBufferInputStream,
&mBufferOutputStream,
ctxt, mListener,
NS_FILE_TRANSPORT_SEGMENT_SIZE,
NS_FILE_TRANSPORT_BUFFER_SIZE);
if (NS_FAILED(rv)) return rv;
mContext = ctxt;
NS_IF_ADDREF(mContext);
@ -270,6 +416,145 @@ nsFileChannel::AsyncWrite(nsIInputStream *fromStream,
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////////////
// nsIRunnable methods:
////////////////////////////////////////////////////////////////////////////////
NS_IMETHODIMP
nsFileChannel::Run(void)
{
while (mState != QUIESCENT && !mSuspended) {
Process();
}
return NS_OK;
}
static NS_METHOD
nsWriteToFile(void* closure,
const char* fromRawSegment,
PRUint32 toOffset,
PRUint32 count,
PRUint32 *writeCount)
{
nsIOutputStream* outStr = (nsIOutputStream*)closure;
nsresult rv = outStr->Write(fromRawSegment, count, writeCount);
return rv;
}
void
nsFileChannel::Process(void)
{
nsAutoLock lock(mLock);
switch (mState) {
case START_READ: {
nsISupports* fs;
NS_ASSERTION(mSourceOffset == 0, "implement seek");
if (mListener) {
mStatus = mListener->OnStartBinding(mContext); // always send the start notification
if (NS_FAILED(mStatus)) goto error;
}
mStatus = NS_NewTypicalInputFileStream(&fs, mSpec);
if (NS_FAILED(mStatus)) goto error;
mStatus = fs->QueryInterface(nsIInputStream::GetIID(), (void**)&mFileStream);
NS_RELEASE(fs);
if (NS_FAILED(mStatus)) goto error;
mState = READING;
break;
}
case READING: {
if (NS_FAILED(mStatus)) goto error;
nsIInputStream* fileStr = NS_STATIC_CAST(nsIInputStream*, mFileStream);
PRUint32 inLen;
mStatus = fileStr->GetLength(&inLen);
if (NS_FAILED(mStatus)) goto error;
PRUint32 amt;
mStatus = mBufferOutputStream->WriteFrom(fileStr, inLen, &amt);
if (NS_FAILED(mStatus)) goto error;
// and feed the buffer to the application via the buffer stream:
if (mListener) {
mStatus = mListener->OnDataAvailable(mContext, mBufferInputStream, mSourceOffset, amt);
if (NS_FAILED(mStatus)) goto error;
}
mSourceOffset += amt;
// stay in the READING state
break;
}
case START_WRITE: {
nsISupports* fs;
if (mListener) {
mStatus = mListener->OnStartBinding(mContext); // always send the start notification
if (NS_FAILED(mStatus)) goto error;
}
mStatus = NS_NewTypicalOutputFileStream(&fs, mSpec);
if (NS_FAILED(mStatus)) goto error;
mStatus = fs->QueryInterface(nsIOutputStream::GetIID(), (void**)&mFileStream);
NS_RELEASE(fs);
if (NS_FAILED(mStatus)) goto error;
mState = WRITING;
break;
}
case WRITING: {
if (NS_FAILED(mStatus)) goto error;
#if 0
PRUint32 amt;
mStatus = mBuffer->ReadSegments(nsWriteToFile, mFileStream, (PRUint32)-1, &amt);
if (mStatus == NS_BASE_STREAM_EOF) goto error;
if (NS_FAILED(mStatus)) goto error;
nsAutoMonitor mon(mBuffer);
mon.Notify();
mSourceOffset += amt;
#endif
// stay in the WRITING state
break;
}
case ENDING: {
mBufferOutputStream->Flush();
NS_IF_RELEASE(mBufferOutputStream);
mBufferOutputStream = nsnull;
NS_IF_RELEASE(mBufferInputStream);
mBufferInputStream = nsnull;
NS_IF_RELEASE(mFileStream);
mFileStream = nsnull;
NS_IF_RELEASE(mContext);
mContext = nsnull;
if (mListener) {
// XXX where do we get the error message?
(void)mListener->OnStopBinding(mContext, mStatus, nsnull);
}
mState = QUIESCENT;
break;
}
case QUIESCENT: {
NS_NOTREACHED("trying to continue a quiescent file transfer");
break;
}
}
return;
error:
mState = ENDING;
return;
}
////////////////////////////////////////////////////////////////////////////////
// From nsIFileChannel
////////////////////////////////////////////////////////////////////////////////
@ -555,119 +840,3 @@ nsFileChannel::Execute(const char *args)
}
////////////////////////////////////////////////////////////////////////////////
// nsIRunnable methods:
NS_IMETHODIMP
nsFileChannel::Run(void)
{
while (mState != ENDED && !mSuspended) {
Process();
}
return NS_OK;
}
void
nsFileChannel::Process(void)
{
nsAutoLock lock(mLock);
switch (mState) {
case START_READ: {
nsISupports* fs;
mStatus = mListener->OnStartBinding(mContext); // always send the start notification
if (NS_FAILED(mStatus)) goto error;
mStatus = NS_NewTypicalInputFileStream(&fs, mSpec);
if (NS_FAILED(mStatus)) goto error;
mStatus = fs->QueryInterface(nsIInputStream::GetIID(), (void**)&mFileStream);
NS_RELEASE(fs);
if (NS_FAILED(mStatus)) goto error;
mStatus = NS_NewBuffer(&mBuffer, NS_FILE_TRANSPORT_BUFFER_SIZE,
NS_FILE_TRANSPORT_BUFFER_SIZE);
if (NS_FAILED(mStatus)) goto error;
mStatus = NS_NewBufferInputStream(&mBufferStream, mBuffer, PR_FALSE);
if (NS_FAILED(mStatus)) goto error;
mState = READING;
break;
}
case READING: {
if (NS_FAILED(mStatus)) goto error;
PRUint32 amt;
nsIInputStream* inStr = NS_STATIC_CAST(nsIInputStream*, mFileStream);
PRUint32 inLen;
mStatus = inStr->GetLength(&inLen);
if (NS_FAILED(mStatus)) goto error;
mStatus = mBuffer->WriteFrom(inStr, inLen, &amt);
if (mStatus == NS_BASE_STREAM_EOF) goto error;
if (NS_FAILED(mStatus)) goto error;
// and feed the buffer to the application via the byte buffer stream:
// XXX maybe amt should be mBufferStream->GetLength():
mStatus = mListener->OnDataAvailable(mContext, mBufferStream, mSourceOffset, amt);
if (NS_FAILED(mStatus)) goto error;
mSourceOffset += amt;
// stay in the READING state
break;
}
case START_WRITE: {
nsISupports* fs;
mStatus = mListener->OnStartBinding(mContext); // always send the start notification
if (NS_FAILED(mStatus)) goto error;
mStatus = NS_NewTypicalOutputFileStream(&fs, mSpec);
if (NS_FAILED(mStatus)) goto error;
mStatus = fs->QueryInterface(nsIOutputStream::GetIID(), (void**)&mFileStream);
NS_RELEASE(fs);
if (NS_FAILED(mStatus)) goto error;
mStatus = NS_NewBuffer(&mBuffer, NS_FILE_TRANSPORT_BUFFER_SIZE,
NS_FILE_TRANSPORT_BUFFER_SIZE);
if (NS_FAILED(mStatus)) goto error;
mStatus = NS_NewBufferInputStream(&mBufferStream, mBuffer, PR_FALSE);
if (NS_FAILED(mStatus)) goto error;
mState = WRITING;
break;
}
case WRITING: {
break;
}
case ENDING: {
NS_IF_RELEASE(mBufferStream);
mBufferStream = nsnull;
NS_IF_RELEASE(mFileStream);
mFileStream = nsnull;
NS_IF_RELEASE(mContext);
mContext = nsnull;
// XXX where do we get the error message?
(void)mListener->OnStopBinding(mContext, mStatus, nsnull);
mState = ENDED;
break;
}
case ENDED: {
NS_NOTREACHED("trying to continue an ended file transfer");
break;
}
}
return;
error:
mState = ENDING;
return;
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -30,6 +30,7 @@ class nsFileProtocolHandler;
class nsIBaseStream;
class nsIBuffer;
class nsIBufferInputStream;
class nsIBufferOutputStream;
class nsFileChannel : public nsIFileChannel, public nsIRunnable {
public:
@ -139,18 +140,19 @@ public:
static NS_METHOD
Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
nsresult Init(const char* verb, nsIURI* uri, nsIEventSinkGetter* getter,
nsresult Init(nsFileProtocolHandler* handler,
const char* verb, nsIURI* uri, nsIEventSinkGetter* getter,
nsIEventQueue* queue);
void Process(void);
enum State {
QUIESCENT,
START_READ,
READING,
START_WRITE,
WRITING,
ENDING,
ENDED
ENDING
};
protected:
@ -167,9 +169,9 @@ protected:
PRBool mSuspended;
// state variables:
nsIBaseStream* mFileStream; // cast to nsIInputStream/nsIOutputStream for reading/writing
nsIBuffer* mBuffer;
nsIBufferInputStream* mBufferStream;
nsIBaseStream* mFileStream; // cast to nsIInputStream/nsIOutputStream for reading/Writing
nsIBufferInputStream* mBufferInputStream;
nsIBufferOutputStream* mBufferOutputStream;
nsresult mStatus;
PRUint32 mSourceOffset;
PRInt32 mAmount;
@ -178,6 +180,7 @@ private:
PRLock* mLock;
};
#define NS_FILE_TRANSPORT_BUFFER_SIZE (4*1024)
#define NS_FILE_TRANSPORT_SEGMENT_SIZE (4*1024)
#define NS_FILE_TRANSPORT_BUFFER_SIZE (32*1024)
#endif // nsFileChannel_h__

View File

@ -38,12 +38,15 @@ nsFileProtocolHandler::nsFileProtocolHandler()
NS_INIT_REFCNT();
}
#define NS_FILE_TRANSPORT_WORKER_STACK_SIZE (8*1024)
nsresult
nsFileProtocolHandler::Init()
{
nsresult rv;
rv = NS_NewThreadPool(&mPool, NS_FILE_TRANSPORT_WORKER_COUNT,
NS_FILE_TRANSPORT_WORKER_COUNT, 8*1024);
NS_FILE_TRANSPORT_WORKER_COUNT,
NS_FILE_TRANSPORT_WORKER_STACK_SIZE);
return rv;
}
@ -80,7 +83,7 @@ nsFileProtocolHandler::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult
NS_IMETHODIMP
nsFileProtocolHandler::GetScheme(char* *result)
{
*result = nsCRT::strdup("ftp");
*result = nsCRT::strdup("file");
if (*result == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
@ -116,7 +119,7 @@ nsFileProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
{
nsresult rv;
// Ftp URLs (currently) have no additional structure beyond that provided by standard
// file: URLs (currently) have no additional structure beyond that provided by standard
// URLs, so there is no "outer" given to CreateInstance
nsIURI* url;
@ -136,14 +139,6 @@ nsFileProtocolHandler::NewURI(const char *aSpec, nsIURI *aBaseURI,
return rv;
}
// XXX this is the default port for ftp. we need to strip out the actual
// XXX requested port.
rv = url->SetPort(21);
if (NS_FAILED(rv)) {
NS_RELEASE(url);
return rv;
}
*result = url;
return rv;
}
@ -160,7 +155,7 @@ nsFileProtocolHandler::NewChannel(const char* verb, nsIURI* url,
rv = nsFileChannel::Create(nsnull, nsIFileChannel::GetIID(), (void**)&channel);
if (NS_FAILED(rv)) return rv;
rv = channel->Init(verb, url, eventSinkGetter, eventQueue);
rv = channel->Init(this, verb, url, eventSinkGetter, eventQueue);
if (NS_FAILED(rv)) {
NS_RELEASE(channel);
return rv;

View File

@ -828,7 +828,8 @@ nsFtpConnectionThread::Run() {
nsIBufferInputStream* in;
nsIBuffer* buf;
rv = NS_NewBuffer(&buf, 4 * 1024, 16 * 1024);
rv = NS_NewBuffer(&buf, NS_FTP_THREAD_SEGMENT_SIZE,
NS_FTP_THREAD_BUFFER_SIZE, nsnull);
rv = NS_NewBufferInputStream(&in, buf);
if (NS_FAILED(rv)) {
mState = FTP_ERROR;
@ -943,7 +944,8 @@ nsFtpConnectionThread::Run() {
nsIBufferInputStream* in;
nsIBuffer* buf;
rv = NS_NewBuffer(&buf, 4 * 1024, 16 * 1024);
rv = NS_NewBuffer(&buf, NS_FTP_THREAD_SEGMENT_SIZE,
NS_FTP_THREAD_BUFFER_SIZE, nsnull);
rv = NS_NewBufferInputStream(&in, buf);
if (NS_FAILED(rv)) {
mState = FTP_ERROR;

View File

@ -173,3 +173,6 @@ private:
nsIStreamListener* mListener; // the listener we want to call
// during our event firing.
};
#define NS_FTP_THREAD_SEGMENT_SIZE (4*1024)
#define NS_FTP_THREAD_BUFFER_SIZE (16*1024)

View File

@ -80,7 +80,8 @@ nsHTTPRequest::Build()
NS_ERROR("Request already built!");
nsIBuffer* buf;
rv = NS_NewBuffer(&buf, 4 * 1024, 16 * 1024);
rv = NS_NewBuffer(&buf, NS_HTTP_REQUEST_SEGMENT_SIZE,
NS_HTTP_REQUEST_BUFFER_SIZE, nsnull);
if (NS_FAILED(rv)) return rv;
rv = NS_NewBufferInputStream(&m_Request, buf);
if (NS_SUCCEEDED(rv))

View File

@ -304,4 +304,7 @@ protected:
nsHTTPChannel* m_pConnection;
};
#define NS_HTTP_REQUEST_SEGMENT_SIZE (4*1024)
#define NS_HTTP_REQUEST_BUFFER_SIZE (16*1024)
#endif /* _nsHTTPRequest_h_ */

View File

@ -216,7 +216,8 @@ Simulated_nsFileTransport_Run(nsReader* reader, const char* path)
if (NS_FAILED(rv)) goto done;
nsIBuffer* buf;
rv = NS_NewBuffer(&buf, NS_FILE_TRANSPORT_BUFFER_SIZE, NS_FILE_TRANSPORT_BUFFER_SIZE);
rv = NS_NewBuffer(&buf, NS_FILE_TRANSPORT_BUFFER_SIZE,
NS_FILE_TRANSPORT_BUFFER_SIZE, nsnull);
rv = NS_NewBufferInputStream(&bufStr, buf);
if (NS_FAILED(rv)) goto done;

View File

@ -239,7 +239,7 @@ main(int argc, char* argv[])
PRUint32 bytesWritten;
nsIBuffer* buf;
rv = NS_NewBuffer(&buf, 1024, 4096);
rv = NS_NewBuffer(&buf, 1024, 4096, nsnull);
rv = NS_NewBufferInputStream(&stream, buf);
if (NS_FAILED(rv)) return rv;

View File

@ -342,7 +342,7 @@ TestConnection::TestConnection(const char* aHostName, PRInt32 aPort, PRBool aAsy
// Create a stream for the data being written to the server...
if (NS_SUCCEEDED(rv)) {
nsIBuffer* buf;
rv = NS_NewBuffer(&buf, 1024, 4096);
rv = NS_NewBuffer(&buf, 1024, 4096, nsnull);
rv = NS_NewBufferInputStream(&mStream, buf);
}
}

View File

@ -30,7 +30,8 @@ PROG3 = .\$(OBJDIR)\TestSocketIO.exe
PROG4 = .\$(OBJDIR)\TestProtocols.exe
PROG5 = .\$(OBJDIR)\TestSocketTransport.exe
PROG6 = .\$(OBJDIR)\urltest.exe
PROGRAMS = $(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6)
PROG7 = .\$(OBJDIR)\TestFileInput2.exe
PROGRAMS = $(PROG1) $(PROG2) $(PROG3) $(PROG4) $(PROG5) $(PROG6) $(PROG7)
LCFLAGS=-DUSE_NSREG -GX
@ -84,3 +85,5 @@ $(PROG4): $(OBJDIR) TestProtocols.cpp
$(PROG5): $(OBJDIR) TestSocketTransport.cpp
$(PROG6): $(OBJDIR) urltest.cpp
$(PROG7): $(OBJDIR) TestFileInput2.cpp