clean up stream converter code, 243888, patch by brofield@jellycan.com, r=ducarroz, sr=bienvenu

This commit is contained in:
bienvenu%nventure.com 2004-06-01 17:22:01 +00:00
Родитель 2c7e977b7e
Коммит 012185855c
2 изменённых файлов: 238 добавлений и 284 удалений

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

@ -21,6 +21,7 @@
*
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
* Brodie Thiesfield <brofield@jellycan.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -92,7 +93,7 @@ bridge_create_stream(nsIMimeEmitter *newEmitter,
nsStreamConverter *newPluginObj2,
nsIURI *uri,
nsMimeOutputType format_out,
PRUint32 whattodo,
PRUint32 whattodo,
nsIChannel *aChannel)
{
if ( (format_out == nsMimeOutput::nsMimeMessageDraftOrTemplate) ||
@ -205,15 +206,15 @@ bridge_new_new_uri(void *bridgeStream, nsIURI *aURI, PRInt32 aOutputType)
if (aOutputType != nsMimeOutput::nsMimeMessageDraftOrTemplate &&
aOutputType != nsMimeOutput::nsMimeMessageEditorTemplate)
{
nsCOMPtr<nsIMsgMailNewsUrl> msgurl (do_QueryInterface(aURI));
if (msgurl)
{
nsCOMPtr<nsIMsgWindow> msgWindow;
msgurl->GetMsgWindow(getter_AddRefs(msgWindow));
if (msgWindow)
nsCOMPtr<nsIMsgMailNewsUrl> msgurl (do_QueryInterface(aURI));
if (msgurl)
{
msgWindow->SetMailCharacterSet(*default_charset);
msgWindow->SetCharsetOverride(*override_charset);
nsCOMPtr<nsIMsgWindow> msgWindow;
msgurl->GetMsgWindow(getter_AddRefs(msgWindow));
if (msgWindow)
{
msgWindow->SetMailCharacterSet(*default_charset);
msgWindow->SetCharsetOverride(*override_charset);
}
}
}
@ -319,71 +320,85 @@ bridge_set_mime_stream_converter_listener(void *bridgeStream, nsIMimeStreamConve
return NS_OK;
}
// find a query element in a url and return a pointer to it's data
// (query must be in the form "query=")
static const char *
FindQueryElementData(const char * aUrl, const char * aQuery)
{
if (aUrl && aQuery)
{
size_t queryLen = 0; // we don't call strlen until we need to
aUrl = PL_strcasestr(aUrl, aQuery);
while (aUrl)
{
if (!queryLen)
queryLen = strlen(aQuery);
if (*(aUrl-1) == '&' || *(aUrl-1) == '?')
return aUrl + queryLen;
aUrl = PL_strcasestr(aUrl + queryLen, aQuery);
}
}
return nsnull;
}
// case-sensitive test for string prefixing. If |string| is prefixed
// by |prefix| then a pointer to the next character in |string| following
// the prefix is returned. If it is not a prefix then |nsnull| is returned.
static const char *
SkipPrefix(const char *aString, const char *aPrefix)
{
while (*aPrefix)
if (*aPrefix++ != *aString++)
return nsnull;
return aString;
}
//
// Utility routines needed by this interface...
// Utility routines needed by this interface
//
nsresult
nsStreamConverter::DetermineOutputFormat(const char *url, nsMimeOutputType *aNewType)
nsStreamConverter::DetermineOutputFormat(const char *aUrl, nsMimeOutputType *aNewType)
{
// Default to html the entire document...
*aNewType = nsMimeOutput::nsMimeMessageQuoting;
// Do sanity checking...
if ( (!url) || (!*url) )
// sanity checking
NS_ENSURE_ARG_POINTER(aNewType);
if (!aUrl || !*aUrl)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
// default to html for the entire document
*aNewType = nsMimeOutput::nsMimeMessageQuoting;
mOutputFormat = "text/html";
return NS_OK;
}
char *format = PL_strcasestr(url, "?outformat=");
char *part = PL_strcasestr(url, "?part=");
char *header = PL_strcasestr(url, "?header=");
if (!format) format = PL_strcasestr(url, "&outformat=");
if (!part) part = PL_strcasestr(url, "&part=");
if (!header) header = PL_strcasestr(url, "&header=");
// shorten the url that we test for the query strings by skipping directly
// to the part where the query strings begin.
const char *queryPart = PL_strchr(aUrl, '?');
// First, did someone pass in a desired output format. They will be able to
// pass in any content type (i.e. image/gif, text/html, etc...but the "/" will
// have to be represented via the "%2F" value
const char *format = FindQueryElementData(queryPart, "outformat=");
if (format)
{
format += strlen("?outformat=");
//NOTE: I've done a file contents search of every file (*.*) in the mozilla
// directory tree and there is not a single location where the string "outformat"
// is added to any URL. It appears that this code has been orphaned off by a change
// elsewhere and is no longer required. It will be removed in the future unless
// someone complains.
NS_ABORT_IF_FALSE(PR_FALSE, "Is this code actually being used?");
while (*format == ' ')
++format;
if ((format) && (*format))
if (*format)
{
char *ptr;
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup(format);
CRTFREEIF(mOverrideFormat);
mOverrideFormat = nsCRT::strdup("raw");
ptr = mOutputFormat;
do
{
if ( (*ptr == '?') || (*ptr == '&') ||
(*ptr == ';') || (*ptr == ' ') )
{
*ptr = '\0';
break;
}
else if (*ptr == '%')
{
if ( (*(ptr+1) == '2') &&
( (*(ptr+2) == 'F') || (*(ptr+2) == 'f') )
)
{
*ptr = '/';
memmove(ptr+1, ptr+3, strlen(ptr+3));
*(ptr + strlen(ptr+3) + 1) = '\0';
ptr += 3;
}
}
} while (*ptr++);
mOverrideFormat = "raw";
// set mOutputFormat to the supplied format, ensure that we replace any
// %2F strings with the slash character
const char *nextField = PL_strpbrk(format, "&; ");
mOutputFormat.Assign(format, nextField ? nextField - format : -1);
mOutputFormat.ReplaceSubstring("%2F", "/");
mOutputFormat.ReplaceSubstring("%2f", "/");
// Don't muck with this data!
*aNewType = nsMimeOutput::nsMimeMessageRaw;
@ -391,136 +406,90 @@ nsStreamConverter::DetermineOutputFormat(const char *url, nsMimeOutputType *aNe
}
}
if (!part)
// is this is a part that should just come out raw
const char *part = FindQueryElementData(queryPart, "part=");
if (part)
{
if (header)
{
PRInt32 lenOfHeader = strlen("?header=");
// default for parts
mOutputFormat = "raw";
*aNewType = nsMimeOutput::nsMimeMessageRaw;
char *ptr2 = PL_strcasestr ("only", (header+lenOfHeader));
char *ptr3 = PL_strcasestr ("quote", (header+lenOfHeader));
char *ptr4 = PL_strcasestr ("quotebody", (header+lenOfHeader));
char *ptr5 = PL_strcasestr ("none", (header+lenOfHeader));
char *ptr6 = PL_strcasestr ("print", (header+lenOfHeader));
char *ptr7 = PL_strcasestr ("saveas", (header+lenOfHeader));
char *ptr8 = PL_strcasestr ("src", (header+lenOfHeader));
char *ptr9 = PL_strcasestr ("filter", (header+lenOfHeader));
if (ptr5)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
}
else if (ptr2)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/xml");
*aNewType = nsMimeOutput::nsMimeMessageHeaderDisplay;
}
else if (ptr3)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageQuoting;
}
else if (ptr4)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageBodyQuoting;
}
else if (ptr6)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessagePrintOutput;
}
else if (ptr7)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageSaveAs;
}
else if (ptr8)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/plain");
*aNewType = nsMimeOutput::nsMimeMessageSource;
}
else if (ptr9)
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageFilterSniffer;
}
}
else
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
}
}
else // this is a part that should just come out raw!
{
// if we are being asked to fetch a part....it should have a
// content type appended to it...if it does, we want to remember
// that as mOutputFormat
if (part)
const char * typeField = FindQueryElementData(queryPart, "type=");
if (typeField)
{
char * typeField = PL_strcasestr(url, "&type=");
if (typeField)
// store the real content type...mOutputFormat gets deleted later on...
// and make sure we only get our own value.
char *nextField = PL_strchr(typeField, '&');
mRealContentType.Assign(typeField, nextField ? nextField - typeField : -1);
if (mRealContentType.EqualsIgnoreCase("message/rfc822"))
{
// store the real content type...mOutputFormat gets deleted later on...
// and make sure we only get our own value.
char *nextField = PL_strcasestr(typeField + strlen("&type="),"&");
if (nextField)
{
*nextField = 0;
mRealContentType = typeField + strlen("&type=");
*nextField = '&';
}
else
mRealContentType = typeField + strlen("&type=");
if (mRealContentType.EqualsIgnoreCase("message/rfc822"))
{
mRealContentType = "x-message-display";
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
}
else if (mRealContentType.EqualsIgnoreCase("x-message-display"))
{
mRealContentType = "";
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
*aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
}
else
{
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("raw");
*aNewType = nsMimeOutput::nsMimeMessageRaw;
}
return NS_OK;
mRealContentType = "x-message-display";
mOutputFormat = "text/html";
*aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
}
else if (mRealContentType.EqualsIgnoreCase("x-message-display"))
{
mRealContentType = "";
mOutputFormat = "text/html";
*aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
}
}
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("raw");
*aNewType = nsMimeOutput::nsMimeMessageRaw;
return NS_OK;
}
// if using the header query
const char *header = FindQueryElementData(queryPart, "header=");
if (header)
{
struct HeaderType {
const char * headerType;
const char * outputFormat;
nsMimeOutputType mimeOutputType;
};
// place most commonly used options at the top
static const struct HeaderType rgTypes[] =
{
{ "filter", "text/html", nsMimeOutput::nsMimeMessageFilterSniffer },
{ "quotebody", "text/html", nsMimeOutput::nsMimeMessageBodyQuoting },
{ "print", "text/html", nsMimeOutput::nsMimeMessagePrintOutput },
{ "only", "text/xml", nsMimeOutput::nsMimeMessageHeaderDisplay },
{ "none", "text/html", nsMimeOutput::nsMimeMessageBodyDisplay },
{ "quote", "text/html", nsMimeOutput::nsMimeMessageQuoting },
{ "saveas", "text/html", nsMimeOutput::nsMimeMessageSaveAs },
{ "src", "text/plain", nsMimeOutput::nsMimeMessageSource }
};
// find the requested header in table, ensure that we don't match on a prefix
// by checking that the following character is either null or the next query element
const char * remainder;
for (int n = 0; n < NS_ARRAY_LENGTH(rgTypes); ++n)
{
remainder = SkipPrefix(header, rgTypes[n].headerType);
if (remainder && (*remainder == '\0' || *remainder == '&'))
{
mOutputFormat = rgTypes[n].outputFormat;
*aNewType = rgTypes[n].mimeOutputType;
return NS_OK;
}
}
}
// default to html for just the body
mOutputFormat = "text/html";
*aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
return NS_OK;
}
nsresult
nsStreamConverter::InternalCleanup(void)
{
CRTFREEIF(mOutputFormat);
CRTFREEIF(mDesiredOutputType);
CRTFREEIF(mOverrideFormat);
if (mBridgeStream)
{
bridge_destroy_stream(mBridgeStream);
@ -536,18 +505,13 @@ nsStreamConverter::InternalCleanup(void)
nsStreamConverter::nsStreamConverter()
{
// Init member variables...
mOverrideFormat = nsnull;
mWrapperOutput = PR_FALSE;
mBridgeStream = NULL;
mTotalRead = 0;
mOutputFormat = nsCRT::strdup("text/html");
mDoneParsing = PR_FALSE;
mOutputFormat = "text/html";
mAlreadyKnowOutputType = PR_FALSE;
mForwardInline = PR_FALSE;
mDesiredOutputType = nsnull;
mPendingChannel = nsnull;
mPendingRequest = nsnull;
mPendingContext = nsnull;
}
@ -577,72 +541,58 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
nsresult rv = NS_OK;
mOutListener = aOutListener;
CRTFREEIF(mDesiredOutputType);
// mscott --> we need to look at the url and figure out what the correct output type is...
nsMimeOutputType newType;
nsMimeOutputType newType = mOutputType;
if (!mAlreadyKnowOutputType)
{
nsCAutoString urlSpec;
rv = aURI->GetSpec(urlSpec);
DetermineOutputFormat(urlSpec.get(), &newType);
mAlreadyKnowOutputType = PR_TRUE;
mOutputType = newType;
}
else
newType = mOutputType;
mOutputType = newType;
switch (newType)
{
case nsMimeOutput::nsMimeMessageSplitDisplay: // the wrapper HTML output to produce the split header/body display
case nsMimeOutput::nsMimeMessageSplitDisplay: // the wrapper HTML output to produce the split header/body display
mWrapperOutput = PR_TRUE;
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
mOutputFormat = "text/html";
break;
case nsMimeOutput::nsMimeMessageHeaderDisplay: // the split header/body display
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/xml");
mOutputFormat = "text/xml";
break;
case nsMimeOutput::nsMimeMessageBodyDisplay: // the split header/body display
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
mOutputFormat = "text/html";
break;
case nsMimeOutput::nsMimeMessageQuoting: // all HTML quoted output
case nsMimeOutput::nsMimeMessageSaveAs: // Save as operation
case nsMimeOutput::nsMimeMessageBodyQuoting: // only HTML body quoted output
case nsMimeOutput::nsMimeMessageQuoting: // all HTML quoted output
case nsMimeOutput::nsMimeMessageSaveAs: // Save as operation
case nsMimeOutput::nsMimeMessageBodyQuoting: // only HTML body quoted output
case nsMimeOutput::nsMimeMessagePrintOutput: // all Printing output
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
mOutputFormat = "text/html";
break;
case nsMimeOutput::nsMimeMessageDecrypt:
case nsMimeOutput::nsMimeMessageRaw: // the raw RFC822 data (view source) and attachments
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("raw");
case nsMimeOutput::nsMimeMessageRaw: // the raw RFC822 data and attachments
mOutputFormat = "raw";
break;
case nsMimeOutput::nsMimeMessageSource: // the raw RFC822 data (view source) and attachments
CRTFREEIF(mOutputFormat);
CRTFREEIF(mOverrideFormat);
mOutputFormat = nsCRT::strdup("text/plain");
mOverrideFormat = nsCRT::strdup("raw");
mOutputFormat = "text/plain";
mOverrideFormat = "raw";
break;
case nsMimeOutput::nsMimeMessageDraftOrTemplate: // Loading drafts & templates
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("message/draft");
mOutputFormat = "message/draft";
break;
case nsMimeOutput::nsMimeMessageEditorTemplate: // Loading templates into editor
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
mOutputFormat = "text/html";
break;
case nsMimeOutput::nsMimeMessageFilterSniffer: // output all displayable part as raw
CRTFREEIF(mOutputFormat);
mOutputFormat = nsCRT::strdup("text/html");
mOutputFormat = "text/html";
break;
default:
@ -650,8 +600,8 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
}
// the following output channel stream is used to fake the content type for people who later
// call into us..
// the following output channel stream is used to fake the content type for people who later
// call into us..
nsXPIDLCString contentTypeToUse;
GetContentType(getter_Copies(contentTypeToUse));
// mscott --> my theory is that we don't need this fake outgoing channel. Let's use the
@ -674,7 +624,7 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
(newType != nsMimeOutput::nsMimeMessageEditorTemplate) )
{
nsCAutoString categoryName ("@mozilla.org/messenger/mimeemitter;1?type=");
if (mOverrideFormat)
if (!mOverrideFormat.IsEmpty())
categoryName += mOverrideFormat;
else
categoryName += mOutputFormat;
@ -699,7 +649,7 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
// now we want to create a pipe which we'll use for converting the data...
rv = NS_NewPipe(getter_AddRefs(mInputStream), getter_AddRefs(mOutputStream),
NS_STREAM_CONVERTER_SEGMENT_SIZE,
NS_STREAM_CONVERTER_BUFFER_SIZE,
/* PR_UINT32_MAX */ NS_STREAM_CONVERTER_BUFFER_SIZE,
PR_TRUE, PR_TRUE);
// initialize our emitter
@ -720,12 +670,12 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
rv = pPrefBranch->GetBoolPref(PREF_MAIL_DISPLAY_GLYPH,&enable_emoticons);
if (NS_FAILED(rv) || enable_emoticons)
{
whattodo = whattodo | mozITXTToHTMLConv::kGlyphSubstitution;
whattodo = whattodo | mozITXTToHTMLConv::kGlyphSubstitution;
}
rv = pPrefBranch->GetBoolPref(PREF_MAIL_DISPLAY_STRUCT,&enable_structs);
if (NS_FAILED(rv) || enable_structs)
{
whattodo = whattodo | mozITXTToHTMLConv::kStructPhrase;
whattodo = whattodo | mozITXTToHTMLConv::kStructPhrase;
}
}
@ -751,19 +701,21 @@ NS_IMETHODIMP nsStreamConverter::Init(nsIURI *aURI, nsIStreamListener * aOutList
NS_IMETHODIMP nsStreamConverter::GetContentType(char **aOutputContentType)
{
if (!aOutputContentType)
return NS_ERROR_NULL_POINTER;
if (!aOutputContentType)
return NS_ERROR_NULL_POINTER;
// since this method passes a string through an IDL file we need to use nsMemory to allocate it
// and not nsCRT::strdup!
// since this method passes a string through an IDL file we need to use nsMemory to allocate it
// and not nsCRT::strdup!
// (1) check to see if we have a real content type...use it first...
if (!mRealContentType.IsEmpty())
*aOutputContentType = ToNewCString(mRealContentType);
else if (nsCRT::strcasecmp(mOutputFormat, "raw") == 0)
*aOutputContentType = (char *) nsMemory::Clone(UNKNOWN_CONTENT_TYPE, strlen(UNKNOWN_CONTENT_TYPE) + 1);
else
*aOutputContentType = (char *) nsMemory::Clone(mOutputFormat, strlen(mOutputFormat) + 1);
return NS_OK;
else if (mOutputFormat.EqualsIgnoreCase("raw"))
{
*aOutputContentType = (char *) nsMemory::Clone(UNKNOWN_CONTENT_TYPE, sizeof(UNKNOWN_CONTENT_TYPE));
}
else
*aOutputContentType = ToNewCString(mOutputFormat);
return NS_OK;
}
//
@ -782,13 +734,13 @@ nsStreamConverter::SetMimeOutputType(nsMimeOutputType aType)
NS_IMETHODIMP nsStreamConverter::GetMimeOutputType(nsMimeOutputType *aOutFormat)
{
nsresult rv = NS_OK;
if (aOutFormat)
*aOutFormat = mOutputType;
else
rv = NS_ERROR_NULL_POINTER;
nsresult rv = NS_OK;
if (aOutFormat)
*aOutFormat = mOutputType;
else
rv = NS_ERROR_NULL_POINTER;
return rv;
return rv;
}
//
@ -833,19 +785,19 @@ nsStreamConverter::GetIdentity(nsIMsgIdentity * *aIdentity)
{
if (!aIdentity) return NS_ERROR_NULL_POINTER;
/*
We don't have an identity for the local folders account,
We don't have an identity for the local folders account,
we will return null but it is not an error!
*/
*aIdentity = mIdentity;
NS_IF_ADDREF(*aIdentity);
*aIdentity = mIdentity;
NS_IF_ADDREF(*aIdentity);
return NS_OK;
}
NS_IMETHODIMP
nsStreamConverter::SetIdentity(nsIMsgIdentity * aIdentity)
{
mIdentity = aIdentity;
return NS_OK;
mIdentity = aIdentity;
return NS_OK;
}
NS_IMETHODIMP
@ -872,7 +824,8 @@ nsStreamConverter::GetOriginalMsgURI(char ** result)
// networking library...
//
nsresult
nsStreamConverter::OnDataAvailable(nsIRequest *request, nsISupports *ctxt,
nsStreamConverter::OnDataAvailable(nsIRequest *request,
nsISupports *ctxt,
nsIInputStream *aIStream,
PRUint32 sourceOffset,
PRUint32 aLength)
@ -902,7 +855,6 @@ const char output[] = "\
if (mEmitter)
mEmitter->Write(outBuf, strlen(outBuf), &written);
mTotalRead += written;
// rhp: will this stop the stream???? Not sure.
return NS_ERROR_FAILURE;
@ -912,7 +864,6 @@ const char output[] = "\
if (!buf)
return NS_ERROR_OUT_OF_MEMORY; /* we couldn't allocate the object */
mTotalRead += aLength;
readLen = aLength;
aIStream->Read(buf, aLength, &readLen);
@ -953,8 +904,6 @@ const char output[] = "\
}
PR_FREEIF(buf);
if (NS_FAILED(rc))
mDoneParsing = PR_TRUE;
return rc;
}
@ -991,10 +940,20 @@ nsStreamConverter::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
}
}
// forward the start rquest to any listeners
if (mOutListener)
mOutListener->OnStartRequest(request, ctxt);
return NS_OK;
// forward the start request to any listeners
if (mOutListener)
{
if (mOutputType == nsMimeOutput::nsMimeMessageRaw)
{
//we need to delay the on start request until we have figure out the real content type
mPendingRequest = request;
mPendingContext = ctxt;
}
else
mOutListener->OnStartRequest(request, ctxt);
}
return NS_OK;
}
//
@ -1093,30 +1052,33 @@ nsStreamConverter::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresul
nsresult nsStreamConverter::Close()
{
mOutgoingChannel = nsnull;
mEmitter = nsnull;
mOutListener = nsnull;
return NS_OK;
mOutgoingChannel = nsnull;
mEmitter = nsnull;
mOutListener = nsnull;
return NS_OK;
}
// nsIStreamConverter implementation
// No syncronous conversion at this time.
NS_IMETHODIMP nsStreamConverter::Convert(nsIInputStream *aFromStream,
const PRUnichar *aFromType,
const PRUnichar *aToType,
nsISupports *aCtxt, nsIInputStream **_retval)
NS_IMETHODIMP nsStreamConverter::Convert(nsIInputStream *aFromStream,
const PRUnichar *aFromType,
const PRUnichar *aToType,
nsISupports *aCtxt,
nsIInputStream **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
// Stream converter service calls this to initialize the actual stream converter (us).
NS_IMETHODIMP nsStreamConverter::AsyncConvertData(const PRUnichar *aFromType, const PRUnichar *aToType,
nsIStreamListener *aListener, nsISupports *aCtxt)
NS_IMETHODIMP nsStreamConverter::AsyncConvertData(const PRUnichar *aFromType,
const PRUnichar *aToType,
nsIStreamListener *aListener,
nsISupports *aCtxt)
{
nsresult rv = NS_OK;
nsresult rv = NS_OK;
nsCOMPtr<nsIMsgQuote> aMsgQuote = do_QueryInterface(aCtxt, &rv);
nsCOMPtr<nsIChannel> aChannel;
nsCOMPtr<nsIChannel> aChannel;
if (aMsgQuote)
{
@ -1131,27 +1093,21 @@ NS_IMETHODIMP nsStreamConverter::AsyncConvertData(const PRUnichar *aFromType, co
aChannel = do_QueryInterface(aCtxt, &rv);
}
if (aToType)
{
CRTFREEIF(mDesiredOutputType);
mDesiredOutputType = nsCRT::strdup(aToType);
}
NS_ASSERTION(aChannel && NS_SUCCEEDED(rv), "mailnews mime converter has to have the channel passed in...");
if (NS_FAILED(rv)) return rv;
NS_ASSERTION(aChannel && NS_SUCCEEDED(rv), "mailnews mime converter has to have the channel passed in...");
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> aUri;
aChannel->GetURI(getter_AddRefs(aUri));
return Init(aUri, aListener, aChannel);
nsCOMPtr<nsIURI> aUri;
aChannel->GetURI(getter_AddRefs(aUri));
return Init(aUri, aListener, aChannel);
}
NS_IMETHODIMP nsStreamConverter::FirePendingStartRequest()
{
if (mPendingChannel && mOutListener)
if (mPendingRequest && mOutListener)
{
mOutListener->OnStartRequest(mPendingChannel, mPendingContext);
mPendingChannel = nsnull;
mOutListener->OnStartRequest(mPendingRequest, mPendingContext);
mPendingRequest = nsnull;
mPendingContext = nsnull;
}
return NS_OK;
}
}

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

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Brodie Thiesfield <brofield@jellycan.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -82,38 +83,35 @@ private:
// the input and output streams form a pipe...they need to be passed around together..
nsCOMPtr<nsIOutputStream> mOutputStream; // output stream
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsIInputStream> mInputStream;
nsCOMPtr<nsIStreamListener> mOutListener; // output stream listener
nsCOMPtr<nsIChannel> mOutgoingChannel;
nsCOMPtr<nsIChannel> mOutgoingChannel;
nsCOMPtr<nsIMimeEmitter> mEmitter; // emitter being used...
nsCOMPtr<nsIURI> mURI; // URI being processed
nsMimeOutputType mOutputType; // the output type we should use for the operation
PRBool mAlreadyKnowOutputType;
PRUnichar * mDesiredOutputType; // the output content type passed into AsyncConvertData..
nsCOMPtr<nsIMimeEmitter> mEmitter; // emitter being used...
nsCOMPtr<nsIURI> mURI; // URI being processed
nsMimeOutputType mOutputType; // the output type we should use for the operation
PRBool mAlreadyKnowOutputType;
void *mBridgeStream; // internal libmime data stream
PRInt32 mTotalRead; // Counter variable
void *mBridgeStream; // internal libmime data stream
// Type of output, entire message, header only, body only
char *mOutputFormat;
nsCString mOutputFormat;
nsCString mRealContentType; // if we know the content type for real, this will be set (used by attachments)
char *mOverrideFormat; // this is a possible override for emitter creation
nsCString mOverrideFormat; // this is a possible override for emitter creation
PRBool mWrapperOutput; // Should we output the frame split message display
PRBool mDoneParsing; // If this is true, we've already been told by libmime to stop sending
// data so don't feed the parser any more!
nsCOMPtr<nsIMimeStreamConverterListener> mMimeStreamConverterListener;
PRBool mForwardInline;
nsCOMPtr<nsIMsgIdentity> mIdentity;
nsCOMPtr<nsIMimeStreamConverterListener> mMimeStreamConverterListener;
PRBool mForwardInline;
nsCOMPtr<nsIMsgIdentity> mIdentity;
nsCString mOriginalMsgURI;
#ifdef DEBUG_mscott
PRTime mConvertContentTime;
#endif
nsIChannel * mPendingChannel; //Will be use whenn we need to delay to fire onStartRequest
nsISupports * mPendingContext; //Will be use whenn we need to delay to fire onStartRequest
nsIRequest * mPendingRequest; // used when we need to delay to fire onStartRequest
nsISupports * mPendingContext; // used when we need to delay to fire onStartRequest
};
#endif /* nsStreamConverter_h_ */