зеркало из https://github.com/mozilla/gecko-dev.git
not in main build - added comments and collapsed interface method definitions into related macros
This commit is contained in:
Родитель
63ba955ba3
Коммит
e1ba01e5de
|
@ -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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче