 |
 |
|
 |
 |
 |
Stream Converter Interface
(nsIStreamConverter)
by Richard H. Pizzarro <rhp@netscape.com>
Contents
Overview
An general purpose interface needs to be defined
to allow the integration of stream converters to the Gecko architecture
(in particular, netlib). A prime example of a stream converter is the libmime
component that currently resides in the Communicator client. libmime is
responsible for conversion of "message/RFC822" streams to various formats
(such as HTML for display). Currently, libmime is a statically linked library
that exposes a C API for use by libnet, but this should take the form of
an XP-COM interface that would allow for external modules to be added,
updated, etc. as development proceeds.
Example Call
Flow
Before we get into the details of any API, we
should discuss the general call flow of what we are trying to accomplish
with this stream converter interface. In our example, we will use the IMAP
Protocol handler and the operation will be rendering an MHTML message retrieved
from an IMAP server.
-
The user clicks on a message listed in the Messenger
FE. This message resides on an IMAP server so a URL to retrieve the server
will be fired by the FE
-
The netlib/IMAP protocol handler starts the process
of downloading the message from the IMAP server
-
The MIME type for the message is identified to be
"message/rfc822". Since the user wishes to display this message in an HTML
display window, the protocol handler needs to identify and initialize a
stream converter than can convert an "message/rfc822" stream to HTML.
-
The IMAP protocol handler would query the Stream
Converter Manager which had a table of all the available stream converter
factories and the format conversions that they support. (Note: this discovery
process and the Stream Converter Manager is not explained in this document).
-
The IMAP Protocol Handler would create and instance
of the RFC822-HTML converter
-
The IMAP Protocol Handler would set the following
on the converter:
-
Output stream for the RFC822-HTML converter. This
is the stream where converted output will be written to after processing
by the stream converter.
-
The output listener on the RFC822-HTML converter.
Some explanation is necessary on why we should set the output listener.
Consider the following case:
IMAP PROTOCOL HANDLER
feeds RFC822 data to the stream converter
|
RFC822 to HTML STREAM CONVERTER
processes RFC822 data and returns an
HTML stream
|
HTML RENDERING ENGINE
displays the HTML stream
|
|
In this situation, it would be nice to have the flexibility
for both of the following options:
-
Have the converted HTML stream be passed back to
the IMAP Protocol handler and from there, it will be fed into the HTML
rendering engine
-
Have the stream converter directly feed the data
into the HTML rendering engine without any processing required by the IMAP
protocol handler
For option #2, we will need the stream converter
to notify the output listener via the OnDataAvailable() method. In order
to do this, the RFC822-HTML converter will need to know the output listener
for processed data.
-
After creating the RFC822-HTML converter, the OnStartBinding()
method will be called to notify the stream converter that the data flow
is starting
-
The RFC822-HTML->OnDataAvailable() method will be
called to notify the stream converter of new data available for conversion.
-
The RFC822-HTML converter will process the data and
write the output to the previously set output stream
-
IF the IMAP Protocol handler set the output listener
on the converter, the RFC822-HTML converter will be responsible for calling
the OnDataAvailable() method on these listeners. If not, the converter
will return
-
The IMAP Protocol Handler would continue receiving
data from the network socket and notifying the stream converter until the
end of the stream is reached.
-
When the stream is completed (or interrupted) the
IMAP Protocol Handler will call the StopBinding() method for the stream
converter and the this will complete the operation
API
Now that we have an understanding of the general call flow for a stream
converter, we should start discussing the XP-COM interface for these modules.
First, we will define a general nsIStreamConverter
interface that will be subclassed with unique ClassID's for all of the
various stream converters. For example, nsIStreamConverter
is
the general class definition for a stream converter, but
nsIRFC822toHTMLStreamConverter
which supports the nsIStreamConverter
interface would be the specific RFC822 to HTML stream converter. (Note:
A registry of converters and the formats they support would need to be
set on a machine and managed by the Stream Converter Manager for use at
runtime)
With all of this in mind, lets look at a definition of the general class
and a specific RFC822 to HTML stream converter.
#ifndef nsIStreamConverter_h_
#define nsIStreamConverter_h_
#include "nsIStreamListener.h"
#include "nsIOutputStream.h"
// {C9CDF8E5-95FA-11d2-8807-00805F5A1FB8}
#define NS_ISTREAM_CONVERTER_IID \
{ 0xc9cdf8e5, 0x95fa, 0x11d2, \
{ 0x88, 0x7, 0x0, 0x80, 0x5f, 0x5a, 0x1f, 0xb8 } };
class nsIStreamConverter : public nsIStreamListener {
public:
//
// This is the output stream where the stream
converter will write processed data after
// conversion.
//
NS_IMETHOD SetOutputStream(nsIOutputStream *outStream)
= 0;
//
// The output listener can be set to allow for
the flexibility of having the stream converter
// directly notify the listener of the output
stream for any processed/converter data. If
// this output listener is not set, the data
will be written into the output stream but it is
// the responsibility of the client of the stream
converter to handle the resulting data.
//
NS_IMETHOD SetOutputListener(nsIStreamListener
*outListner) = 0;
};
#endif /* nsIStreamConverter_h_ */
|
nsRFC822toHTMLStreamConverter.h
|
#ifndef nsRFC822toHTMLStreamConverter_h_
#define nsRFC822toHTMLStreamConverter_h_
#include "nsIStreamConverter.h"
//
// A specific stream converter will be specified for each format-in/format-out
// pairing.
//
// {22DB1685-AA68-11d2-8809-00805F5A1FB8}
#define NS_RFC822_HTML_STREAM_CONVERTER_CID \
{ 0x22db1685, 0xaa68, 0x11d2, \
{ 0x88, 0x9, 0x0, 0x80, 0x5f, 0x5a, 0x1f, 0xb8 } };
class nsRFC822toHTMLStreamConverter : public nsIStreamConverter
{
public:
void *tagData;
};
#endif /* nsRFC822toHTMLStreamConverter_h_ */
|
 |
 |