зеркало из https://github.com/mozilla/gecko-dev.git
First check in of the mailbox protocol module.
This commit is contained in:
Родитель
84ad13250c
Коммит
a73271b892
|
@ -0,0 +1,404 @@
|
|||
/* -*- 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 "msgCore.h"
|
||||
|
||||
#include "nsMailboxProtocol.h"
|
||||
#include "nscore.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
||||
#include "rosetta.h"
|
||||
|
||||
#include "allxpstr.h"
|
||||
#include "prtime.h"
|
||||
#include "prlog.h"
|
||||
#include "prerror.h"
|
||||
#include "prprf.h"
|
||||
|
||||
static NS_DEFINE_IID(kIMailboxUrlIID, NS_IMAILBOXURL_IID);
|
||||
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
|
||||
static NS_DEFINE_IID(kIInputStreamIID, NS_IINPUTSTREAM_IID);
|
||||
|
||||
/* the output_buffer_size must be larger than the largest possible line
|
||||
* 2000 seems good for news
|
||||
*
|
||||
* jwz: I increased this to 4k since it must be big enough to hold the
|
||||
* entire button-bar HTML, and with the new "mailto" format, that can
|
||||
* contain arbitrarily long header fields like "references".
|
||||
*
|
||||
* fortezza: proxy auth is huge, buffer increased to 8k (sigh).
|
||||
*/
|
||||
#define OUTPUT_BUFFER_SIZE (4096*2)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// TEMPORARY HARD CODED FUNCTIONS
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// END OF TEMPORARY HARD CODED FUNCTIONS
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* the following macros actually implement addref, release and query interface for our component. */
|
||||
NS_IMPL_ADDREF(nsMailboxProtocol)
|
||||
NS_IMPL_RELEASE(nsMailboxProtocol)
|
||||
NS_IMPL_QUERY_INTERFACE(nsMailboxProtocol, kIStreamListenerIID); /* we need to pass in the interface ID of this interface */
|
||||
|
||||
nsMailboxProtocol::nsMailboxProtocol(nsIURL * aURL, nsITransport * transportLayer)
|
||||
{
|
||||
/* the following macro is used to initialize the ref counting data */
|
||||
NS_INIT_REFCNT();
|
||||
Initialize(aURL, transportLayer);
|
||||
}
|
||||
|
||||
nsMailboxProtocol::~nsMailboxProtocol()
|
||||
{
|
||||
// release all of our event sinks
|
||||
NS_IF_RELEASE(m_mailboxParser);
|
||||
|
||||
// free our local state
|
||||
PR_FREEIF(m_dataBuf);
|
||||
|
||||
// free handles on all networking objects...
|
||||
NS_IF_RELEASE(m_outputStream);
|
||||
NS_IF_RELEASE(m_outputConsumer);
|
||||
NS_IF_RELEASE(m_transport);
|
||||
}
|
||||
|
||||
void nsMailboxProtocol::Initialize(nsIURL * aURL, nsITransport * transportLayer)
|
||||
{
|
||||
NS_PRECONDITION(aURL, "invalid URL passed into MAILBOX Protocol");
|
||||
|
||||
m_flags = 0;
|
||||
|
||||
// grab a reference to the transport interface
|
||||
if (transportLayer)
|
||||
NS_ADDREF(transportLayer);
|
||||
|
||||
m_transport = transportLayer;
|
||||
|
||||
// query the URL for a nsIMAILBOXUrl
|
||||
m_runningUrl = NULL; // initialize to NULL
|
||||
|
||||
if (aURL)
|
||||
{
|
||||
nsresult rv = aURL->QueryInterface(kIMailboxUrlIID, (void **)&m_runningUrl);
|
||||
if (NS_SUCCEEDED(rv) && m_runningUrl)
|
||||
{
|
||||
// okay, now fill in our event sinks...Note that each getter ref counts before
|
||||
// it returns the interface to us...we'll release when we are done
|
||||
}
|
||||
}
|
||||
|
||||
m_outputStream = NULL;
|
||||
m_outputConsumer = NULL;
|
||||
|
||||
nsresult rv = m_transport->GetOutputStream(&m_outputStream);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "ooops, transport layer unable to create an output stream");
|
||||
rv = m_transport->GetOutputStreamConsumer(&m_outputConsumer);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "ooops, transport layer unable to provide us with an output consumer!");
|
||||
|
||||
// register self as the consumer for the socket...
|
||||
rv = m_transport->SetInputStreamConsumer((nsIStreamListener *) this);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to register MAILBOX instance as a consumer on the socket");
|
||||
|
||||
m_dataBuf = (char *) PR_Malloc(sizeof(char) * OUTPUT_BUFFER_SIZE);
|
||||
m_dataBufSize = OUTPUT_BUFFER_SIZE;
|
||||
m_mailboxParser = nsnull;
|
||||
|
||||
m_nextState = MAILBOX_READ_FOLDER;
|
||||
m_initialState = MAILBOX_READ_FOLDER;
|
||||
|
||||
m_urlInProgress = PR_FALSE;
|
||||
m_socketIsOpen = PR_FALSE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// we suppport the nsIStreamListener interface
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Whenever data arrives from the connection, core netlib notifices the protocol by calling
|
||||
// OnDataAvailable. We then read and process the incoming data from the input stream.
|
||||
NS_IMETHODIMP nsMailboxProtocol::OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream, PRUint32 aLength)
|
||||
{
|
||||
// right now, this really just means turn around and process the url
|
||||
ProcessMailboxState(aURL, aIStream, aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMailboxProtocol::OnStartBinding(nsIURL* aURL, const char *aContentType)
|
||||
{
|
||||
// extract the appropriate event sinks from the url and initialize them in our protocol data
|
||||
// the URL should be queried for a nsINewsURL. If it doesn't support a news URL interface then
|
||||
// we have an error.
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
// stop binding is a "notification" informing us that the stream associated with aURL is going away.
|
||||
NS_IMETHODIMP nsMailboxProtocol::OnStopBinding(nsIURL* aURL, nsresult aStatus, const PRUnichar* aMsg)
|
||||
{
|
||||
// what can we do? we can close the stream?
|
||||
m_urlInProgress = PR_FALSE;
|
||||
|
||||
if (m_nextState == MAILBOX_READ_FOLDER && m_mailboxParser)
|
||||
{
|
||||
// we need to inform our mailbox parser that there is no more incoming data...
|
||||
m_mailboxParser->OnStopBinding(aURL, 0, nsnull);
|
||||
|
||||
}
|
||||
|
||||
// and we want to mark ourselves for deletion or some how inform our protocol manager that we are
|
||||
// available for another url if there is one....
|
||||
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// End of nsIStreamListenerSupport
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRInt32 nsMailboxProtocol::ReadLine(nsIInputStream * inputStream, PRUint32 length, char ** line)
|
||||
{
|
||||
// I haven't looked into writing this yet. We have a couple of possibilities:
|
||||
// (1) insert ReadLine *yuck* into here or better yet into the nsIInputStream
|
||||
// then we can just turn around and call it here.
|
||||
// OR
|
||||
// (2) we write "protocol" specific code for news which looks for a CRLF in the incoming
|
||||
// stream. If it finds it, that's our new line that we put into @param line. We'd
|
||||
// need a buffer (m_dataBuf) to store extra info read in from the stream.....
|
||||
|
||||
// read out everything we've gotten back and return it in line...this won't work for much but it does
|
||||
// get us going...
|
||||
|
||||
// XXX: please don't hold this quick "algorithm" against me. I just want to read just one
|
||||
// line for the stream. I promise this is ONLY temporary to test out NNTP. We need a generic
|
||||
// way to read one line from a stream. For now I'm going to read out one character at a time.
|
||||
// (I said it was only temporary =)) and test for newline...
|
||||
|
||||
PRUint32 numBytesToRead = 0; // MAX # bytes to read from the stream
|
||||
PRUint32 numBytesRead = 0; // total number bytes we have read from the stream during this call
|
||||
inputStream->GetLength(&length); // refresh the length in case it has changed...
|
||||
|
||||
if (length > OUTPUT_BUFFER_SIZE)
|
||||
numBytesToRead = OUTPUT_BUFFER_SIZE;
|
||||
else
|
||||
numBytesToRead = length;
|
||||
|
||||
m_dataBuf[0] = '\0';
|
||||
PRUint32 numBytesLastRead = 0; // total number of bytes read in the last cycle...
|
||||
do
|
||||
{
|
||||
inputStream->Read(m_dataBuf, numBytesRead /* offset into m_dataBuf */, 1 /* read just one byte */, &numBytesLastRead);
|
||||
numBytesRead += numBytesLastRead;
|
||||
} while (numBytesRead <= numBytesToRead && numBytesLastRead > 0 && m_dataBuf[numBytesRead-1] != '\n');
|
||||
|
||||
m_dataBuf[numBytesRead] = '\0'; // null terminate the string.
|
||||
|
||||
// oops....we also want to eat up the '\n' and the \r'...
|
||||
if (numBytesRead > 1 && m_dataBuf[numBytesRead-2] == '\r')
|
||||
m_dataBuf[numBytesRead-2] = '\0'; // hit both cr and lf...
|
||||
else
|
||||
if (numBytesRead > 0 && (m_dataBuf[numBytesRead-1] == '\r' || m_dataBuf[numBytesRead-1] == '\n'))
|
||||
m_dataBuf[numBytesRead-1] = '\0';
|
||||
|
||||
if (line)
|
||||
*line = m_dataBuf;
|
||||
return numBytesRead;
|
||||
}
|
||||
|
||||
/*
|
||||
* Writes the data contained in dataBuffer into the current output stream. It also informs
|
||||
* the transport layer that this data is now available for transmission.
|
||||
* Returns a positive number for success, 0 for failure (not all the bytes were written to the
|
||||
* stream, etc). We need to make another pass through this file to install an error system (mscott)
|
||||
*/
|
||||
|
||||
PRInt32 nsMailboxProtocol::SendData(const char * dataBuffer)
|
||||
{
|
||||
PRUint32 writeCount = 0;
|
||||
PRInt32 status = 0;
|
||||
|
||||
NS_PRECONDITION(m_outputStream && m_outputConsumer, "no registered consumer for our output");
|
||||
if (dataBuffer && m_outputStream)
|
||||
{
|
||||
nsresult rv = m_outputStream->Write(dataBuffer, 0 /* offset */, PL_strlen(dataBuffer), &writeCount);
|
||||
if (NS_SUCCEEDED(rv) && writeCount == PL_strlen(dataBuffer))
|
||||
{
|
||||
// notify the consumer that data has arrived
|
||||
// HACK ALERT: this should really be m_runningUrl once we have NNTP url support...
|
||||
nsIInputStream *inputStream = NULL;
|
||||
m_outputStream->QueryInterface(kIInputStreamIID , (void **) &inputStream);
|
||||
if (inputStream)
|
||||
{
|
||||
m_outputConsumer->OnDataAvailable(m_runningUrl, inputStream, writeCount);
|
||||
NS_RELEASE(inputStream);
|
||||
}
|
||||
status = 1; // mscott: we need some type of MK_OK? MK_SUCCESS? Arrgghhh
|
||||
}
|
||||
else // the write failed for some reason, returning 0 trips an error by the caller
|
||||
status = 0; // mscott: again, I really want to add an error code here!!
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Begin protocol state machine functions...
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRInt32 nsMailboxProtocol::LoadURL(nsIURL * aURL)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRInt32 status = 0;
|
||||
nsIMailboxUrl * mailboxUrl = nsnull;
|
||||
HG77067
|
||||
if (aURL)
|
||||
{
|
||||
// let's verify that the new url being loaded is in fact a mailbox url...
|
||||
const char * protocol = nsnull;
|
||||
rv = aURL->GetProtocol(&protocol);
|
||||
NS_ASSERTION(protocol && PL_strcmp(protocol, "mailbox") == 0, "this is not a mailbox url!");
|
||||
|
||||
rv = aURL->QueryInterface(kIMailboxUrlIID, (void **) &mailboxUrl);
|
||||
if (NS_SUCCEEDED(rv) && mailboxUrl)
|
||||
{
|
||||
NS_IF_RELEASE(m_runningUrl);
|
||||
m_runningUrl = mailboxUrl; // we have transferred ref cnt contro to m_runningUrl
|
||||
|
||||
// mscott: right now, the only mailbox url we process is a open mailbox folder url...
|
||||
// eventually we'll port over the rest of the code and have to do more up front url
|
||||
// testing to figure out the correct next state....
|
||||
|
||||
// extract the mailbox parser..
|
||||
NS_IF_RELEASE(m_mailboxParser);
|
||||
rv = m_runningUrl->GetMailboxParser(&m_mailboxParser);
|
||||
m_nextState = MAILBOX_READ_FOLDER;
|
||||
|
||||
// okay now kick us off to the next state...
|
||||
// our first state is a process state so drive the state machine...
|
||||
PRBool transportOpen = PR_FALSE;
|
||||
m_transport->IsTransportOpen(&transportOpen);
|
||||
m_urlInProgress = PR_TRUE;
|
||||
if (transportOpen == PR_FALSE)
|
||||
{
|
||||
m_transport->Open(m_runningUrl); // opening the url will cause to get notified when the connection is established
|
||||
}
|
||||
else // the connection is already open so we should begin processing our new url...
|
||||
{
|
||||
// mscott - I think mailbox urls always come in fresh for each mailbox protocol connection
|
||||
// so we should always be calling m_transport->open(our url)....
|
||||
NS_ASSERTION(0, "mscott -- I don't think we should get here for mailbox urls");
|
||||
status = ProcessMailboxState(m_runningUrl, nsnull, 0);
|
||||
}
|
||||
} // if we received an MAILBOX url...
|
||||
} // if we received a url!
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
PRInt32 nsMailboxProtocol::ReadFolderResponse(nsIInputStream * inputStream, PRUint32 length)
|
||||
{
|
||||
// okay we are doing a folder read in 8K chunks of a mail folder....
|
||||
// this is almost too easy....we can just forward the data in this stream on to our
|
||||
// folder parser object!!!
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (m_mailboxParser)
|
||||
rv = m_mailboxParser->OnDataAvailable(m_runningUrl, inputStream, length); // let the parser deal with it...
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
m_nextState = MAILBOX_ERROR_DONE; // drop out of the loop....
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now wait for the next 8K chunk to come in.....
|
||||
SetFlag(MAILBOX_PAUSE_FOR_READ);
|
||||
|
||||
// leave our state alone so when the next chunk of the mailbox comes in we jump to this state
|
||||
// and repeat....how does this process end? Well when the file is done being read in, core net lib
|
||||
// will issue an ::OnStopBinding to us...we'll use that as our sign to drop out of this state and to
|
||||
// close the protocol instance...
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* returns negative if the transfer is finished or error'd out
|
||||
*
|
||||
* returns zero or more if the transfer needs to be continued.
|
||||
*/
|
||||
PRInt32 nsMailboxProtocol::ProcessMailboxState(nsIURL * url, nsIInputStream * inputStream, PRUint32 length)
|
||||
{
|
||||
PRInt32 status = 0;
|
||||
ClearFlag(MAILBOX_PAUSE_FOR_READ); /* already paused; reset */
|
||||
|
||||
while(!TestFlag(MAILBOX_PAUSE_FOR_READ))
|
||||
{
|
||||
|
||||
switch(m_nextState)
|
||||
{
|
||||
case MAILBOX_READ_FOLDER:
|
||||
if (inputStream == nsnull)
|
||||
SetFlag(MAILBOX_PAUSE_FOR_READ); // wait for file socket to read in the next chunk...
|
||||
else
|
||||
status = ReadFolderResponse(inputStream, length);
|
||||
break;
|
||||
case MAILBOX_DONE:
|
||||
m_urlInProgress = PR_FALSE;
|
||||
m_nextState = MAILBOX_FREE;
|
||||
break;
|
||||
|
||||
case MAILBOX_ERROR_DONE:
|
||||
m_nextState = MAILBOX_FREE;
|
||||
break;
|
||||
|
||||
case MAILBOX_FREE:
|
||||
// MAILBOX is a one time use connection so kill it if we get here...
|
||||
CloseConnection();
|
||||
return(-1); /* final end */
|
||||
|
||||
default: /* should never happen !!! */
|
||||
m_nextState = MAILBOX_ERROR_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* check for errors during load and call error
|
||||
* state if found
|
||||
*/
|
||||
if(status < 0 && m_nextState != MAILBOX_FREE)
|
||||
{
|
||||
m_nextState = MAILBOX_ERROR_DONE;
|
||||
/* don't exit! loop around again and do the free case */
|
||||
ClearFlag(MAILBOX_PAUSE_FOR_READ);
|
||||
}
|
||||
} /* while(!MAILBOX_PAUSE_FOR_READ) */
|
||||
|
||||
return(status);
|
||||
}
|
||||
|
||||
PRInt32 nsMailboxProtocol::CloseConnection()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
/* -*- 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.
|
||||
*/
|
||||
|
||||
#ifndef nsMailboxProtocol_h___
|
||||
#define nsMailboxProtocol_h___
|
||||
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsITransport.h"
|
||||
#include "rosetta.h"
|
||||
#include HG40855
|
||||
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIMailboxUrl.h"
|
||||
|
||||
// State Flags (Note, I use the word state in terms of storing
|
||||
// state information about the connection (authentication, have we sent
|
||||
// commands, etc. I do not intend it to refer to protocol state)
|
||||
|
||||
#define MAILBOX_PAUSE_FOR_READ 0x00000001 /* should we pause for the next read */
|
||||
|
||||
/* states of the machine
|
||||
*/
|
||||
typedef enum _MailboxStatesEnum {
|
||||
MAILBOX_READ_FOLDER,
|
||||
MAILBOX_FINISH_OPEN_FOLDER,
|
||||
MAILBOX_OPEN_MESSAGE,
|
||||
MAILBOX_OPEN_STREAM,
|
||||
MAILBOX_READ_MESSAGE,
|
||||
MAILBOX_COMPRESS_FOLDER,
|
||||
MAILBOX_FINISH_COMPRESS_FOLDER,
|
||||
MAILBOX_BACKGROUND,
|
||||
MAILBOX_NULL,
|
||||
MAILBOX_NULL2,
|
||||
MAILBOX_DELIVER_QUEUED,
|
||||
MAILBOX_FINISH_DELIVER_QUEUED,
|
||||
MAILBOX_DONE,
|
||||
MAILBOX_ERROR_DONE,
|
||||
MAILBOX_FREE,
|
||||
MAILBOX_COPY_MESSAGES,
|
||||
MAILBOX_FINISH_COPY_MESSAGES
|
||||
} MailboxStatesEnum;
|
||||
|
||||
class nsMailboxProtocol : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
// Creating a protocol instance requires the URL which needs to be run AND it requires
|
||||
// a transport layer.
|
||||
nsMailboxProtocol(nsIURL * aURL, nsITransport * transportLayer);
|
||||
|
||||
virtual ~nsMailboxProtocol();
|
||||
|
||||
PRInt32 LoadURL(nsIURL * aURL);
|
||||
PRBool IsRunningUrl() { return m_urlInProgress;} // returns true if we are currently running a url and false otherwise...
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// we suppport the nsIStreamListener interface
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// mscott; I don't think we need to worry about this yet so I'll leave it stubbed out for now
|
||||
NS_IMETHOD GetBindInfo(nsIURL* aURL, nsStreamBindingInfo* aInfo) { return NS_OK;} ;
|
||||
|
||||
// Whenever data arrives from the connection, core netlib notifies the protocol by calling
|
||||
// OnDataAvailable. We then read and process the incoming data from the input stream.
|
||||
NS_IMETHOD OnDataAvailable(nsIURL* aURL, nsIInputStream *aIStream, PRUint32 aLength);
|
||||
|
||||
NS_IMETHOD OnStartBinding(nsIURL* aURL, const char *aContentType);
|
||||
|
||||
// stop binding is a "notification" informing us that the stream associated with aURL is going away.
|
||||
NS_IMETHOD OnStopBinding(nsIURL* aURL, nsresult aStatus, const PRUnichar* aMsg);
|
||||
|
||||
// Ideally, a protocol should only have to support the stream listener methods covered above.
|
||||
// However, we don't have this nsIStreamListenerLite interface defined yet. Until then, we are using
|
||||
// nsIStreamListener so we need to add stubs for the heavy weight stuff we don't want to use.
|
||||
|
||||
NS_IMETHOD OnProgress(nsIURL* aURL, PRUint32 aProgress, PRUint32 aProgressMax) { return NS_OK;}
|
||||
NS_IMETHOD OnStatus(nsIURL* aURL, const PRUnichar* aMsg) { return NS_OK;}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// End of nsIStreamListenerSupport
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Flag manipulators
|
||||
PRBool TestFlag (PRUint32 flag) {return flag & m_flags;}
|
||||
void SetFlag (PRUint32 flag) { m_flags |= flag; }
|
||||
void ClearFlag (PRUint32 flag) { m_flags &= ~flag; }
|
||||
|
||||
private:
|
||||
// the following flag is used to determine when a url is currently being run. It is cleared on calls
|
||||
// to ::StopBinding and it is set whenever we call Load on a url
|
||||
PRBool m_urlInProgress;
|
||||
PRBool m_socketIsOpen;
|
||||
PRUint32 m_flags; // used to store flag information
|
||||
nsIMailboxUrl *m_runningUrl; // the nsIMailboxURL that is currently running
|
||||
char *m_dataBuf;
|
||||
PRUint32 m_dataBufSize;
|
||||
PRInt32 m_originalContentLength; /* the content length at the time of calling graph progress */
|
||||
|
||||
// Event sink handles
|
||||
nsIStreamListener *m_mailboxParser;
|
||||
|
||||
// Local state for the current operation
|
||||
|
||||
// Ouput stream for writing commands to the socket
|
||||
nsITransport * m_transport;
|
||||
nsIOutputStream * m_outputStream; // this will be obtained from the transport interface
|
||||
nsIStreamListener * m_outputConsumer; // this will be obtained from the transport interface
|
||||
|
||||
// Generic state information -- What state are we in? What state do we want to go to
|
||||
// after the next response? What was the last response code? etc.
|
||||
MailboxStatesEnum m_nextState;
|
||||
MailboxStatesEnum m_initialState;
|
||||
|
||||
PRInt32 ProcessMailboxState(nsIURL * url, nsIInputStream * inputStream, PRUint32 length);
|
||||
PRInt32 CloseConnection(); // releases and closes down this protocol instance...
|
||||
|
||||
// initialization function given a new url and transport layer
|
||||
void Initialize(nsIURL * aURL, nsITransport * transportLayer);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Communication methods --> Reading and writing protocol
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRInt32 ReadLine(nsIInputStream * inputStream, PRUint32 length, char ** line);
|
||||
|
||||
// SendData not only writes the NULL terminated data in dataBuffer to our output stream
|
||||
// but it also informs the consumer that the data has been written to the stream.
|
||||
PRInt32 SendData(const char * dataBuffer);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Protocol Methods --> This protocol is state driven so each protocol method is
|
||||
// designed to re-act to the current "state". I've attempted to
|
||||
// group them together based on functionality.
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// When parsing a mailbox folder in chunks, this protocol state reads in the current chunk
|
||||
// and forwards it to the mailbox parser.
|
||||
PRInt32 ReadFolderResponse(nsIInputStream * inputStream, PRUint32 length);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// End of Protocol Methods
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
#endif // nsMailboxProtocol_h___
|
Загрузка…
Ссылка в новой задаче