Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
nsStreamConverter Class Reference

#include <nsStreamConverter.h>

Inheritance diagram for nsStreamConverter:
Inheritance graph
[legend]
Collaboration diagram for nsStreamConverter:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsStreamConverter ()
virtual ~nsStreamConverter ()
NS_DECL_ISUPPORTS
NS_DECL_NSIMIMESTREAMCONVERTER
NS_DECL_NSISTREAMCONVERTER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_IMETHOD 
Init (nsIURI *aURI, nsIStreamListener *aOutListener, nsIChannel *aChannel)
NS_IMETHOD GetContentType (char **aOutputContentType)
NS_IMETHOD InternalCleanup (void)
NS_IMETHOD DetermineOutputFormat (const char *url, nsMimeOutputType *newType)
NS_IMETHOD FirePendingStartRequest (void)
nsIInputStream convert (in nsIInputStream aFromStream, in string aFromType, in string aToType, in nsISupports aCtxt)
 SYNCRONOUS VERSION Converts a stream of one type, to a stream of another type.
void asyncConvertData (in string aFromType, in string aToType, in nsIStreamListener aListener, in nsISupports aCtxt)
 ASYNCRONOUS VERSION Converts data arriving via the converter's nsIStreamListener::OnDataAvailable() method from one type to another, pushing the converted data out to the caller via aListener::OnDataAvailable().
void onDataAvailable (in nsIRequest aRequest, in nsISupports aContext, in nsIInputStream aInputStream, in unsigned long aOffset, in unsigned long aCount)
 Called when the next chunk of data (corresponding to the request) may be read without blocking the calling thread.
void onStartRequest (in nsIRequest aRequest, in nsISupports aContext)
 Called to signify the beginning of an asynchronous request.
void onStopRequest (in nsIRequest aRequest, in nsISupports aContext, in nsresult aStatusCode)
 Called to signify the end of an asynchronous request.
void SetMimeOutputType (in nsMimeOutputType aType)
void GetMimeOutputType (out nsMimeOutputType aOutFormat)
void SetStreamURI (in nsIURI aURI)
void SetMimeHeadersListener (in nsIMimeStreamConverterListener listener, in nsMimeOutputType aType)

Public Attributes

attribute PRBool forwardInline
attribute nsIMsgIdentity identity
attribute string originalMsgURI

Private Member Functions

nsresult Close ()

Private Attributes

nsCOMPtr< nsIOutputStreammOutputStream
nsCOMPtr< nsIInputStreammInputStream
nsCOMPtr< nsIStreamListenermOutListener
nsCOMPtr< nsIChannelmOutgoingChannel
nsCOMPtr< nsIMimeEmittermEmitter
nsCOMPtr< nsIURImURI
nsMimeOutputType mOutputType
PRBool mAlreadyKnowOutputType
voidmBridgeStream
nsCString mOutputFormat
nsCString mRealContentType
nsCString mOverrideFormat
PRBool mWrapperOutput
nsCOMPtr
< nsIMimeStreamConverterListener
mMimeStreamConverterListener
PRBool mForwardInline
nsCOMPtr< nsIMsgIdentitymIdentity
nsCString mOriginalMsgURI
nsCString mFromType
nsCString mToType
nsIRequestmPendingRequest
nsISupports * mPendingContext

Detailed Description

Definition at line 55 of file nsStreamConverter.h.


Constructor & Destructor Documentation

Definition at line 525 of file nsStreamConverter.cpp.

Here is the call graph for this function:


Member Function Documentation

void nsIStreamConverter::asyncConvertData ( in string  aFromType,
in string  aToType,
in nsIStreamListener  aListener,
in nsISupports  aCtxt 
) [inherited]

ASYNCRONOUS VERSION Converts data arriving via the converter's nsIStreamListener::OnDataAvailable() method from one type to another, pushing the converted data out to the caller via aListener::OnDataAvailable().

Use this method when you want to proxy (and convert) nsIStreamListener callbacks asynchronously.

Parameters:
aFromTypeThe MIME type of the original/raw data.
aToTypeThe MIME type of the converted data.
aListenerThe listener who receives the converted data.
aCtxtEither an opaque context, or a converter specific context (implementation specific).

Definition at line 1061 of file nsStreamConverter.cpp.

nsIInputStream nsIStreamConverter::convert ( in nsIInputStream  aFromStream,
in string  aFromType,
in string  aToType,
in nsISupports  aCtxt 
) [inherited]

SYNCRONOUS VERSION Converts a stream of one type, to a stream of another type.

Use this method when you have a stream you want to convert.

Parameters:
aFromStreamThe stream representing the original/raw data.
aFromTypeThe MIME type of aFromStream.
aToTypeThe MIME type of the returned stream.
aCtxtEither an opaque context, or a converter specific context (implementation specific).
Returns:
The converted stream. NOTE: The returned stream may not already be converted. An efficient stream converter implementation will converter data on demand rather than buffering the converted data until it is used.

Definition at line 360 of file nsStreamConverter.cpp.

{
  // sanity checking
  NS_ENSURE_ARG_POINTER(aNewType);
  if (!aUrl || !*aUrl)
  {
    // default to html for the entire document
    *aNewType = nsMimeOutput::nsMimeMessageQuoting;
    mOutputFormat = "text/html";
    return NS_OK;
  }

  // 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)
  {
    //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)
    {
      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;
      return NS_OK;
    }
  }

  // is this is a part that should just come out raw
  const char *part = FindQueryElementData(queryPart, "part=");
  if (part && !mToType.Equals("application/vnd.mozilla.xul+xml"))
  {
    // default for parts
    mOutputFormat = "raw";
    *aNewType = nsMimeOutput::nsMimeMessageRaw;

    // 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
    const char * typeField = FindQueryElementData(queryPart, "type=");
    if (typeField && !strncmp(typeField, "application/x-message-display", sizeof("application/x-message-display") - 1))
    {
      const char *secondTypeField = FindQueryElementData(typeField, "type=");
      if (secondTypeField)
        typeField = secondTypeField;
    }
    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.LowerCaseEqualsLiteral("message/rfc822"))
      {
        mRealContentType = "application/x-message-display";
        mOutputFormat = "text/html";
        *aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
      }
      else if (mRealContentType.LowerCaseEqualsLiteral("application/x-message-display"))
      {
        mRealContentType = "";
        mOutputFormat = "text/html";
        *aNewType = nsMimeOutput::nsMimeMessageBodyDisplay;
      }
    }

    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 },
      { "attach",    "raw",        nsMimeOutput::nsMimeMessageAttach }
    };

    // 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;
}

Here is the call graph for this function:

NS_IMETHODIMP nsStreamConverter::GetContentType ( char **  aOutputContentType)

Definition at line 710 of file nsStreamConverter.cpp.

{
  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!
  //  (1) check to see if we have a real content type...use it first...
  if (!mRealContentType.IsEmpty())
    *aOutputContentType = ToNewCString(mRealContentType);
  else if (mOutputFormat.LowerCaseEqualsLiteral("raw"))
  {
    *aOutputContentType = (char *) nsMemory::Clone(UNKNOWN_CONTENT_TYPE, sizeof(UNKNOWN_CONTENT_TYPE));
  }
  else
    *aOutputContentType = ToNewCString(mOutputFormat);
  return NS_OK;
}

Here is the call graph for this function:

Definition at line 545 of file nsStreamConverter.cpp.

{
  NS_ENSURE_ARG_POINTER(aURI);

  nsresult rv = NS_OK; 
  mOutListener = aOutListener;

  // mscott --> we need to look at the url and figure out what the correct output type is...
  nsMimeOutputType newType = mOutputType;
  if (!mAlreadyKnowOutputType)
  {
    nsCAutoString urlSpec;
    rv = aURI->GetSpec(urlSpec);
    DetermineOutputFormat(urlSpec.get(), &newType);
    mAlreadyKnowOutputType = PR_TRUE;
    mOutputType = newType;  
  }
  
  switch (newType)
  {
    case nsMimeOutput::nsMimeMessageSplitDisplay:    // the wrapper HTML output to produce the split header/body display
      mWrapperOutput = PR_TRUE;
      mOutputFormat = "text/html";
      break;
    case nsMimeOutput::nsMimeMessageHeaderDisplay:   // the split header/body display
      mOutputFormat = "text/xml";
      break;
    case nsMimeOutput::nsMimeMessageBodyDisplay:   // the split header/body display
      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::nsMimeMessagePrintOutput:  // all Printing output
      mOutputFormat = "text/html";
      break;
      
    case nsMimeOutput::nsMimeMessageAttach:
    case nsMimeOutput::nsMimeMessageDecrypt:  
    case nsMimeOutput::nsMimeMessageRaw:              // the raw RFC822 data and attachments
      mOutputFormat = "raw";
      break;
      
    case nsMimeOutput::nsMimeMessageSource:      // the raw RFC822 data (view source) and attachments
      mOutputFormat = "text/plain";
      mOverrideFormat = "raw";
      break;
      
    case nsMimeOutput::nsMimeMessageDraftOrTemplate:       // Loading drafts & templates
      mOutputFormat = "message/draft";
      break;
      
    case nsMimeOutput::nsMimeMessageEditorTemplate:       // Loading templates into editor
      mOutputFormat = "text/html";
      break;

    case nsMimeOutput::nsMimeMessageFilterSniffer: // output all displayable part as raw 
      mOutputFormat = "text/html";
      break;

    default:
      NS_ASSERTION(0, "this means I made a mistake in my assumptions");
  }
  
  
  // 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
  // original channel and just set our content type ontop of the original channel...

  aChannel->SetContentType(contentTypeToUse);

  //rv = NS_NewInputStreamChannel(getter_AddRefs(mOutgoingChannel), aURI, nsnull, contentTypeToUse, -1);
  //if (NS_FAILED(rv)) 
  //    return rv;
  
  // Set system principal for this document, which will be dynamically generated 
  
  // We will first find an appropriate emitter in the repository that supports 
  // the requested output format...note, the special exceptions are nsMimeMessageDraftOrTemplate
  // or nsMimeMessageEditorTemplate where we don't need any emitters
  //
  
  if ( (newType != nsMimeOutput::nsMimeMessageDraftOrTemplate) && 
    (newType != nsMimeOutput::nsMimeMessageEditorTemplate) )
  {
    nsCAutoString categoryName ("@mozilla.org/messenger/mimeemitter;1?type=");
    if (!mOverrideFormat.IsEmpty())
      categoryName += mOverrideFormat;
    else
      categoryName += mOutputFormat;
    
    nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
    if (NS_SUCCEEDED(rv))
    {
      nsXPIDLCString contractID;
      catman->GetCategoryEntry("mime-emitter", categoryName.get(), getter_Copies(contractID));
      if (!contractID.IsEmpty())
        categoryName = contractID;
    }

    mEmitter = do_CreateInstance(categoryName.get(), &rv);

    if ((NS_FAILED(rv)) || (!mEmitter))
    {
      return NS_ERROR_OUT_OF_MEMORY;
    }
  }
    
  // 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,
                  /* PR_UINT32_MAX */  NS_STREAM_CONVERTER_BUFFER_SIZE, 
                  PR_TRUE, PR_TRUE);
  
  // initialize our emitter
  if (NS_SUCCEEDED(rv) && mEmitter)
  {
    mEmitter->Initialize(aURI, aChannel, newType);
    mEmitter->SetPipe(mInputStream, mOutputStream);
    mEmitter->SetOutputListener(aOutListener);
  }
  
  PRUint32 whattodo = mozITXTToHTMLConv::kURLs;
  PRBool enable_emoticons = PR_TRUE;
  PRBool enable_structs = PR_TRUE;

  nsCOMPtr<nsIPrefBranch> pPrefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
  if (pPrefBranch)
  {
    rv = pPrefBranch->GetBoolPref(PREF_MAIL_DISPLAY_GLYPH,&enable_emoticons);
    if (NS_FAILED(rv) || enable_emoticons) 
    {
      whattodo = whattodo | mozITXTToHTMLConv::kGlyphSubstitution;
    }
    rv = pPrefBranch->GetBoolPref(PREF_MAIL_DISPLAY_STRUCT,&enable_structs);
    if (NS_FAILED(rv) || enable_structs) 
    {
      whattodo = whattodo | mozITXTToHTMLConv::kStructPhrase;
    }
  }

  if (mOutputType == nsMimeOutput::nsMimeMessageSource)
    return NS_OK;
  else
  {
    mBridgeStream = bridge_create_stream(mEmitter, this, aURI, newType, whattodo, aChannel);
    if (!mBridgeStream)
      return NS_ERROR_OUT_OF_MEMORY;
    else
    {
      SetStreamURI(aURI);

      //Do we need to setup an Mime Stream Converter Listener?
      if (mMimeStreamConverterListener)
        bridge_set_mime_stream_converter_listener((nsMIMESession *)mBridgeStream, mMimeStreamConverterListener, mOutputType);

      return NS_OK;
    }
  }
}

Here is the call graph for this function:

Definition at line 498 of file nsStreamConverter.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIStreamListener::onDataAvailable ( in nsIRequest  aRequest,
in nsISupports  aContext,
in nsIInputStream  aInputStream,
in unsigned long  aOffset,
in unsigned long  aCount 
) [inherited]

Called when the next chunk of data (corresponding to the request) may be read without blocking the calling thread.

The onDataAvailable impl must read exactly |aCount| bytes of data before returning.

Parameters:
aRequestrequest corresponding to the source of the data
aContextuser defined context
aInputStreaminput stream containing the data chunk
aOffsetNumber of bytes that were sent in previous onDataAvailable calls for this request. In other words, the sum of all previous count parameters. If that number is greater than or equal to 2^32, this parameter will be PR_UINT32_MAX (2^32 - 1).
aCountnumber of bytes available in the stream

NOTE: The aInputStream parameter must implement readSegments.

An exception thrown from onDataAvailable has the side-effect of causing the request to be canceled.

void nsIRequestObserver::onStartRequest ( in nsIRequest  aRequest,
in nsISupports  aContext 
) [inherited]

Called to signify the beginning of an asynchronous request.

Parameters:
aRequestrequest being observed
aContextuser defined context

An exception thrown from onStartRequest has the side-effect of causing the request to be canceled.

Here is the caller graph for this function:

void nsIRequestObserver::onStopRequest ( in nsIRequest  aRequest,
in nsISupports  aContext,
in nsresult  aStatusCode 
) [inherited]

Called to signify the end of an asynchronous request.

This call is always preceded by a call to onStartRequest.

Parameters:
aRequestrequest being observed
aContextuser defined context
aStatusCodereason for stopping (NS_OK if completed successfully)

An exception thrown from onStopRequest is generally ignored.

Here is the caller graph for this function:


Member Data Documentation

Definition at line 103 of file nsIMimeStreamConverter.idl.

Definition at line 108 of file nsIMimeStreamConverter.idl.

Definition at line 94 of file nsStreamConverter.h.

Definition at line 96 of file nsStreamConverter.h.

Definition at line 91 of file nsStreamConverter.h.

Definition at line 106 of file nsStreamConverter.h.

Definition at line 110 of file nsStreamConverter.h.

Definition at line 107 of file nsStreamConverter.h.

Definition at line 86 of file nsStreamConverter.h.

Definition at line 105 of file nsStreamConverter.h.

Definition at line 108 of file nsStreamConverter.h.

Definition at line 89 of file nsStreamConverter.h.

Definition at line 88 of file nsStreamConverter.h.

Definition at line 99 of file nsStreamConverter.h.

Definition at line 85 of file nsStreamConverter.h.

Definition at line 93 of file nsStreamConverter.h.

Definition at line 102 of file nsStreamConverter.h.

nsISupports* nsStreamConverter::mPendingContext [private]

Definition at line 116 of file nsStreamConverter.h.

Definition at line 115 of file nsStreamConverter.h.

Definition at line 100 of file nsStreamConverter.h.

Definition at line 111 of file nsStreamConverter.h.

Definition at line 92 of file nsStreamConverter.h.

Definition at line 103 of file nsStreamConverter.h.

Definition at line 109 of file nsIMimeStreamConverter.idl.


The documentation for this class was generated from the following files: