not in main build - added comments and collapsed interface method definitions into related macros

This commit is contained in:
valeski%netscape.com 1999-08-27 15:12:40 +00:00
Родитель 63ba955ba3
Коммит e1ba01e5de
2 изменённых файлов: 63 добавлений и 36 удалений

Просмотреть файл

@ -35,6 +35,8 @@ NS_IMPL_ISUPPORTS2(nsMultiMixedConv, nsIStreamConverter, nsIStreamListener);
// nsIStreamConverter implementation // nsIStreamConverter implementation
// No syncronous conversion at this time.
NS_IMETHODIMP NS_IMETHODIMP
nsMultiMixedConv::Convert(nsIInputStream *aFromStream, nsMultiMixedConv::Convert(nsIInputStream *aFromStream,
const PRUnichar *aFromType, const PRUnichar *aFromType,
@ -43,11 +45,18 @@ nsMultiMixedConv::Convert(nsIInputStream *aFromStream,
return NS_ERROR_NOT_IMPLEMENTED; return NS_ERROR_NOT_IMPLEMENTED;
} }
// Stream converter service calls this to initialize the actual stream converter (us).
NS_IMETHODIMP NS_IMETHODIMP
nsMultiMixedConv::AsyncConvertData(const PRUnichar *aFromType, const PRUnichar *aToType, nsMultiMixedConv::AsyncConvertData(const PRUnichar *aFromType, const PRUnichar *aToType,
nsIStreamListener *aListener, nsISupports *aCtxt) { nsIStreamListener *aListener, nsISupports *aCtxt) {
NS_ASSERTION(aListener && aFromType && aToType, "null pointer passed into multi mixed converter"); NS_ASSERTION(aListener && aFromType && aToType, "null pointer passed into multi mixed converter");
// hook up our final listener. this guy gets the various On*() calls we want to throw
// at him.
//
// WARNING: this listener must be able to handle multiple OnStartRequest, OnDataAvail()
// and OnStopRequest() call combinations. We call of series of these for each sub-part
// in the raw stream.
mFinalListener = aListener; mFinalListener = aListener;
NS_ADDREF(mFinalListener); NS_ADDREF(mFinalListener);
@ -60,10 +69,8 @@ NS_IMETHODIMP
nsMultiMixedConv::OnDataAvailable(nsIChannel *channel, nsISupports *ctxt, nsMultiMixedConv::OnDataAvailable(nsIChannel *channel, nsISupports *ctxt,
nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) { nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count) {
nsresult rv; nsresult rv;
char *buffer = nsnull, *rootMemPtr = nsnull, *delimiter = nsnull, *bndry = nsnull; char *buffer = nsnull, *rootMemPtr = nsnull;
PRUint32 bufLen, read; PRUint32 bufLen, read;
rv = inStr->GetLength(&bufLen);
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(channel, "multimixed converter needs a channel"); NS_ASSERTION(channel, "multimixed converter needs a channel");
@ -73,6 +80,7 @@ nsMultiMixedConv::OnDataAvailable(nsIChannel *channel, nsISupports *ctxt,
nsIHTTPChannel *httpChannel = nsnull; nsIHTTPChannel *httpChannel = nsnull;
rv = channel->QueryInterface(NS_GET_IID(nsIHTTPChannel), (void**)&httpChannel); rv = channel->QueryInterface(NS_GET_IID(nsIHTTPChannel), (void**)&httpChannel);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
char *bndry = nsnull, *delimiter = nsnull;
nsIAtom *header = NS_NewAtom("content-type"); nsIAtom *header = NS_NewAtom("content-type");
if (!header) return NS_ERROR_OUT_OF_MEMORY; if (!header) return NS_ERROR_OUT_OF_MEMORY;
rv = httpChannel->GetResponseHeader(header, &delimiter); rv = httpChannel->GetResponseHeader(header, &delimiter);
@ -81,24 +89,28 @@ nsMultiMixedConv::OnDataAvailable(nsIChannel *channel, nsISupports *ctxt,
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
bndry = PL_strstr(delimiter, "boundary"); bndry = PL_strstr(delimiter, "boundary");
if (!bndry) { if (!bndry) return NS_ERROR_FAILURE;
// if we dont' have a boundary we're hosed.
return NS_ERROR_FAILURE;
}
bndry = PL_strchr(bndry, '='); bndry = PL_strchr(bndry, '=');
if (!bndry) return NS_ERROR_FAILURE; if (!bndry) return NS_ERROR_FAILURE;
bndry += 1; bndry++; // move past the equals sign
nsString2 boundaryString(bndry, eOneByte); nsString2 boundaryString(bndry, eOneByte);
boundaryString.StripWhitespace(); boundaryString.StripWhitespace();
mBoundaryCStr = boundaryString.ToNewCString(); mBoundaryCStr = boundaryString.ToNewCString();
if (!mBoundaryCStr) return NS_ERROR_OUT_OF_MEMORY; if (!mBoundaryCStr) return NS_ERROR_OUT_OF_MEMORY;
mBoundaryStrLen = boundaryString.Length(); mBoundaryStrLen = boundaryString.Length();
} else {
// we couldn't get at the boundary and we need one.
NS_ASSERTION(0, "no http channel to get the multipart boundary from");
return NS_ERROR_FAILURE;
} }
} }
rv = inStr->GetLength(&bufLen);
if (NS_FAILED(rv)) return rv;
rootMemPtr = buffer = (char*)nsAllocator::Alloc(bufLen + 1); rootMemPtr = buffer = (char*)nsAllocator::Alloc(bufLen + 1);
if (!buffer) return NS_ERROR_OUT_OF_MEMORY; if (!buffer) return NS_ERROR_OUT_OF_MEMORY;
@ -106,7 +118,17 @@ nsMultiMixedConv::OnDataAvailable(nsIChannel *channel, nsISupports *ctxt,
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
buffer[bufLen] = '\0'; buffer[bufLen] = '\0';
// search the buffered data for the delimiting token. // Break up the stream into it sub parts and send off an On*() triple combination
// for each subpart.
// This design of HTTP's multipart/x-mixed-replace (see nsMultiMixedConv.h for more info)
// was flawed from the start. This parsing makes the following, poor, assumption about
// the data coming from the server:
//
// - The server will never send a partial boundary token
//
// This assumption is necessary in order for this type to be handled. Also note that
// the server doesn't send any Content-Length information.
char *boundaryLoc = PL_strstr(buffer, mBoundaryCStr); char *boundaryLoc = PL_strstr(buffer, mBoundaryCStr);
do { do {
if (boundaryLoc) { if (boundaryLoc) {
@ -218,8 +240,6 @@ nsMultiMixedConv::OnDataAvailable(nsIChannel *channel, nsISupports *ctxt,
rv = SendData(buffer, mPartChannel, ctxt); rv = SendData(buffer, mPartChannel, ctxt);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
} }
// XXX we can probably break out of the loop here instead of iterating
// XXX again.
boundaryLoc = PL_strstr(buffer, mBoundaryCStr); boundaryLoc = PL_strstr(buffer, mBoundaryCStr);
} }
} else { } else {
@ -261,10 +281,10 @@ nsMultiMixedConv::OnStopRequest(nsIChannel *channel, nsISupports *ctxt,
// nsMultiMixedConv methods // nsMultiMixedConv methods
nsMultiMixedConv::nsMultiMixedConv() { nsMultiMixedConv::nsMultiMixedConv() {
NS_INIT_ISUPPORTS(); NS_INIT_ISUPPORTS();
mFinalListener = nsnull; mFinalListener = nsnull;
mBoundaryCStr = nsnull; mBoundaryCStr = nsnull;
mBoundaryStrLen = mPartCount = 0; mPartChannel = nsnull;
mPartChannel = nsnull; mBoundaryStrLen = mPartCount = 0;
} }
nsMultiMixedConv::~nsMultiMixedConv() { nsMultiMixedConv::~nsMultiMixedConv() {
@ -387,9 +407,7 @@ MultiMixedFactory::CreateInstance(nsISupports *aOuter,
} }
nsresult nsresult
MultiMixedFactory::LockFactory(PRBool aLock) MultiMixedFactory::LockFactory(PRBool aLock){
{
// Not implemented in simplest case.
return NS_OK; return NS_OK;
} }
@ -399,8 +417,7 @@ NSGetFactory(nsISupports* aServMgr,
const nsCID &aClass, const nsCID &aClass,
const char *aClassName, const char *aClassName,
const char *aProgID, const char *aProgID,
nsIFactory **aFactory) nsIFactory **aFactory) {
{
nsresult rv; nsresult rv;
if (aFactory == nsnull) if (aFactory == nsnull)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
@ -421,8 +438,7 @@ NSGetFactory(nsISupports* aServMgr,
extern "C" PR_IMPLEMENT(nsresult) extern "C" PR_IMPLEMENT(nsresult)
NSRegisterSelf(nsISupports* aServMgr , const char* aPath) NSRegisterSelf(nsISupports* aServMgr , const char* aPath) {
{
nsresult rv; nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv)); nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
@ -443,8 +459,7 @@ NSRegisterSelf(nsISupports* aServMgr , const char* aPath)
extern "C" PR_IMPLEMENT(nsresult) extern "C" PR_IMPLEMENT(nsresult)
NSUnregisterSelf(nsISupports* aServMgr, const char* aPath) NSUnregisterSelf(nsISupports* aServMgr, const char* aPath) {
{
nsresult rv; nsresult rv;
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv)); nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));

Просмотреть файл

@ -32,6 +32,26 @@
} }
static NS_DEFINE_CID(kMultiMixedConverterCID, NS_MULTIMIXEDCONVERTER_CID); static NS_DEFINE_CID(kMultiMixedConverterCID, NS_MULTIMIXEDCONVERTER_CID);
// The nsMultiMixedConv stream converter converts a stream of type "multipart/x-mixed-replace"
// to it's subparts. There was some debate as to whether or not the functionality desired
// when HTTP confronted this type required a stream converter. After all, this type really
// prompts various viewer related actions rather than stream conversion. There simply needs
// to be a piece in place that can strip out the multiple parts of a stream of this type, and
// "display" them accordingly.
//
// With that said, this "stream converter" spends more time packaging up the sub parts of the
// main stream and sending them off the destination stream listener, than doing any real
// stream parsing/converting.
//
// WARNING: This converter requires that it's destination stream listener be able to handle
// multiple OnStartRequest(), OnDataAvailable(), and OnStopRequest() call combinations.
// Each series represents the beginning, data production, and ending phase of each sub-
// part of the original stream.
//
// NOTE: this MIME-type is used by HTTP, *not* SMTP, or IMAP.
//
// NOTE: For reference, a general description of how this MIME type should be handled via
// HTTP, see http://home.netscape.com/assist/net_sites/pushpull.html
class nsMultiMixedConv : public nsIStreamConverter { class nsMultiMixedConv : public nsIStreamConverter {
public: public:
@ -39,22 +59,13 @@ public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
// nsIStreamConverter methods // nsIStreamConverter methods
NS_IMETHOD Convert(nsIInputStream *aFromStream, NS_DECL_NSISTREAMCONVERTER
const PRUnichar *aFromType,
const PRUnichar *aToType,
nsISupports *aCtxt, nsIInputStream **_retval);
NS_IMETHOD AsyncConvertData(const PRUnichar *aFromType, const PRUnichar *aToType,
nsIStreamListener *aListener, nsISupports *aCtxt);
// nsIStreamListener methods // nsIStreamListener methods
NS_IMETHOD OnDataAvailable(nsIChannel *channel, nsISupports *ctxt, NS_DECL_NSISTREAMLISTENER
nsIInputStream *inStr, PRUint32 sourceOffset, PRUint32 count);
// nsIStreamObserver methods // nsIStreamObserver methods
NS_IMETHOD OnStartRequest(nsIChannel *channel, nsISupports *ctxt); NS_DECL_NSISTREAMOBSERVER
NS_IMETHOD OnStopRequest(nsIChannel *channel, nsISupports *ctxt,
nsresult status, const PRUnichar *errorMsg);
// nsMultiMixedConv methods // nsMultiMixedConv methods
nsMultiMixedConv(); nsMultiMixedConv();
@ -63,6 +74,7 @@ public:
nsresult SendData(const char *aBuffer, nsIChannel *aChannel, nsISupports *aCtxt); nsresult SendData(const char *aBuffer, nsIChannel *aChannel, nsISupports *aCtxt);
nsresult BuildURI(nsIChannel *aChannel, nsIURI **_retval); nsresult BuildURI(nsIChannel *aChannel, nsIURI **_retval);
// For factory creation.
static NS_METHOD static NS_METHOD
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) { Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) {
nsresult rv; nsresult rv;