Hello all, Doug Turner and myself have been working on revising nsIChannel to allow for overlapped i/o. This goal stems from wanting to be able to have active AsyncRead and AsyncWrite operations on nsSocketTransport. This is desired because it would greatly simplify the task of maintaining persistent/reusable socket connections for FTP, HTTP, and Imap (and potentially other protocols). The problem with the existing nsIChannel interface is that it does not allow one to selectively suspend just one of the read or write operations while keeping the other active. Several solutions were tossed around in an effort to solve this problem. The best suggestion seemed to be to break the IsA relationship between nsIChannel and nsIRequest (recall: nsIRequest defines Suspend, Resume, Cancel, etc.) and then make AsyncRead and AsyncWrite return nsIRequest's. But, this was not enough. It was also necessary to move the transferOffset and transferCount parameters from nsIChannel to parameters on AsyncRead and AsyncWrite, so that for each operation the offset and count could be different. Moreover, this same nsIRequest interface would have to be passed through the methods of nsIStreamObserver, nsIStreamListener, and nsIStreamProvider, so that clients would be able to identify the request being processed. The next hurdle came in trying to decide what to do with the contentType and contentLength nsIChannel attributes. It was not clear from the interface which operation (read or write) these attributes pertained to. This resulted in quite a debate on this newsgroup (see the threads: "Re: Necko Interface Changes", "channel changes", and "content type changes"). Finally, another solution emerged. Instead of trying to make nsIChannel satisfy the design requirements of transports and the design requirements of fetching URIs, it made more sense to break the two into separate interfaces. Hence, nsITransport represents i/o in the classic (and overlapped) sense, while nsIChannel represents the act of fetching data associated with an URI. Moreover, we found that since nsIChannel need not describe transports, its i/o methods could be simplified down to just AsyncOpen and Open (see revised nsIChannel interface below). The operation of writing data to a channel is 1) not common to all channel implementations, and 2) it is done in a very protocol specific way (HTTP, for example, might prefer to get the data in the form of a nsISeekableStream so that it could take advantage of certain HTTP/1.1 features). Plus there are issues with content encoding for upload streams that really are protocol specific. Overview of changes:
(see attached) Issues:
These changes are underway on a branch cut on the 22nd of January. They are nearly complete. Pending acceptance by the community, optimized builds of this branch will be posted on ftp.mozilla.org for testing. Please feel free to join us by testing the branch. The relevant CVS tags are: DOUGT_CHANNEL_CHANGES_01222001_BASE DOUGT_CHANNEL_CHANGES_01222001_BRANCH We are hoping to generate feedback on these changes. Please let us know what you think. Thanks! Darin |
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ #include "nsISupports.idl" #include "nsIRequest.idl" interface nsIStreamListener; interface nsIStreamProvider; interface nsIInputStream; interface nsIOutputStream; interface nsIProgressEventSink; [scriptable, uuid(fd01f9a4-d492-4cf8-b76e-160ffc8c01e8)] interface nsITransport : nsISupports { /** * Get security info for this transport. */ readonly attribute nsISupports securityInfo; /** * Get/set the progress event sink for this transport. */ attribute nsIProgressEventSink progressEventSink; /** * Open an input stream on this transport. * * @param offset - read starting at this offset * @param count - read this many bytes * @param flags - optional transport specific flags */ nsIInputStream openInputStream(in unsigned long offset, in unsigned long count, in unsigned long flags); /** * Open an output stream on this transport. * * @param offset - write starting at this offset * @param count - write no more than this many bytes * @param flags - optional transport specific flags */ nsIOutputStream openOutputStream(in unsigned long offset, in unsigned long count, in unsigned long flags); /** * Asynchronously read data from the transport. * * @param listener - notify this listener when data is available * @param ctxt - opaque parameter passed to listener methods * @param offset - read starting at this offset * @param count - read this many bytes * @param flags - optional transport specific flags */ nsIRequest asyncRead(in nsIStreamListener listener, in nsISupports ctxt, in unsigned long offset, in unsigned long count, in unsigned long flags); /** * Asynchronously write data to the transport. * * @param provider - notify this provider when data can be written * @param ctxt - opaque parameter passed to provider methods * @param offset - write starting at this offset * @param count - write this many bytes * @param flags - optional transport specific flags */ nsIRequest asyncWrite(in nsIStreamProvider provider, in nsISupports ctxt, in unsigned long offset, in unsigned long count, in unsigned long flags); }; [scriptable, uuid(d7abf5a4-ce72-482a-9217-a219a905c019)] interface nsITransportRequest : nsIRequest { /** * Get the transport associated with this request. */ readonly attribute nsITransport transport; };
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ #include "nsIRequest.idl" interface nsIURI; interface nsIInputStream; interface nsIOutputStream; interface nsIStreamObserver; interface nsIStreamListener; interface nsIStreamProvider; interface nsILoadGroup; interface nsIInterfaceRequestor; interface nsIFile; interface nsIStreamIO; typedef unsigned long nsLoadFlags; /** * The nsIChannel interface allows the user to construct I/O requests for * specific protocols, and manage them in a uniform way. Once a channel * is created (via nsIIOService::NewChannel), parameters for that request * may be set by using the channel attributes, or by QueryInterfacing to a * subclass of nsIChannel for protocol-specific parameters. Then the actual * request can be issued in one of several ways: * * - AsyncRead and AsyncWrite allow for asynchronous requests, calling * back the user's stream listener or provider, * - OpenInputStream and OpenOutputStream allow for synchronous reads * and writes on the underlying channel. * * After a request has been completed, the channel is still valid for * accessing protocol-specific results. For example, QueryInterfacing to * nsIHTTPChannel allows response headers to be retrieved that result from * http transactions. * * Note that a channel is really only valid for one request. Reusing a channel * after a request has completed for a subsequent request may have undefined * results, depending on the channel implementation. * * Also of note are a special kind of channel called "transports." Transports * also implement the nsIChannel interface, but operate at a lower level from * protocol channels. The socket and file transports are notable implementations * of transports and allow higher level channels to be implemented. The cache * may also behave as a transport, and possibly things like sound playing services * etc. Transports usually operate in a separate thread and often multiplex * multiple requests for the same kind of service or resources. */ [scriptable, uuid(1788e79e-f947-11d3-8cda-0060b0fc14a3)] interface nsIChannel : nsIRequest { //////////////////////////////////////////////////////////////////////////// // nsIChannel accessors //////////////////////////////////////////////////////////////////////////// /** * Returns the original URL used to construct the channel. * This is used in the case of a redirect or URI "resolution" (e.g. * resolving a resource: URI to a file: URI) so that the original * pre-redirect URI can still be obtained. * * Note that this is distinctly different from the http referrer * (referring URI) which is typically the page that contained the * original URI (accessible from nsIHTTPChannel). */ attribute nsIURI originalURI; /** * Returns the URL to which the channel currently refers. If a redirect * or URI resolution occurs, this accessor returns the current location * to which the channel is referring. */ attribute nsIURI URI; /** * Accesses the owner corresponding to the entity that is * responsible for this channel. Used by security code to grant * or deny privileges to mobile code loaded from this channel. * * Note: This is a strong reference to the owner, so if the owner is also * holding a pointer to the channel, care must be taken to explicitly drop * its reference to the channel -- otherwise a leak will result. */ attribute nsISupports owner; /** * Accesses the load group in which the channel is a currently a member. */ attribute nsILoadGroup loadGroup; /** * Accesses the load attributes for the channel. E.g. setting the load * attributes with the LOAD_QUIET bit set causes the loading process to * not deliver status notifications to the program performing the load, * and to not contribute to keeping any nsILoadGroup it may be contained * in from firing its OnLoadComplete notification. */ attribute nsLoadFlags loadAttributes; /** * Accesses the capabilities callbacks of the channel. This is set by clients * who wish to provide a means to receive progress, status and protocol-specific * notifications. */ attribute nsIInterfaceRequestor notificationCallbacks; /** * Any security information about this channel. This can be null. */ readonly attribute nsISupports securityInfo; /** * Returns the content MIME type of the channel if available. Note that the * content type can often be wrongly specified (wrong file extension, wrong * MIME type, wrong document type stored on a server, etc.) and the caller * most likely wants to verify with the actual data. */ attribute string contentType; /** * Returns the length of the data associated with the channel if available. * If the length is unknown then -1 is returned. */ attribute long contentLength; nsIInputStream open(); void asyncOpen(in nsIStreamListener listener, in nsISupports ctxt); //////////////////////////////////////////////////////////////////////////// // Load attribute flags. These may be or'd together. //////////////////////////////////////////////////////////////////////////// /** * Note that more will follow for each protocol's implementation of a channel, * although channel writers have to be careful to not let the flag bits * overlap. Otherwise, users won't be able to create a single flag word * of load attributes that applies to a number of different channel types. */ /** * No special load attributes -- use defaults: */ const unsigned long LOAD_NORMAL = 0; /** * Don't deliver status notifications to the nsIProgressEventSink, or keep * this load from completing the nsILoadGroup it may belong to: */ const unsigned long LOAD_BACKGROUND = 1 << 0; /** * Used exclusively by the uriloader and docshell to indicate whether or * not this channel corresponds to the toplevel document. */ const unsigned long LOAD_DOCUMENT_URI = 1 << 1; /** * If the end consumer for this load has been retargeted after discovering * it's content, this flag will be set: */ const unsigned long LOAD_RETARGETED_DOCUMENT_URI = 1 << 2; /** * Causes the load of a URL (issued via AsyncRead or AsyncWrite) to be * deferred in order to allow the request to be pipelined for greater * throughput efficiency. Pipelined requests will be forced to load * when the first non-pipelined request is issued. */ const unsigned long ALLOW_PIPELINING = 1 << 3; //////////////////////////////////////////////////////////////////////////// /** * The following flags control caching behavior. Not all protocols pay * attention to all these flags, but they are applicable to more than one * protocol, so they are defined here. */ /** * Don't store data in the disk cache. This can be used to preserve * privacy, e.g. so that no https transactions are recorded, or to avoid * caching a stream to disk that is already stored in a local file, * e.g. the mailbox: protocol. */ const unsigned long INHIBIT_PERSISTENT_CACHING = 1 << 8; /** * Force an end-to-end download of content data from the origin server (and * any intervening proxies that sit between it and the client), e.g. this * flag is used for a shift-reload. */ const unsigned long FORCE_RELOAD = 1 << 9; /** * Force revalidation with server (or proxy) to verify that cached content * is up-to-date, e.g. by comparing last-modified date on server with that * of the cached version. For example, this flag is used when the reload * button is pressed. */ const unsigned long FORCE_VALIDATION = 1 << 10; /** * If the CACHE_AS_FILE flag is set, any stream content is stored in the * cache as a single disk file. Content will not be cached in the memory * cache nor will it be stored in any other type of cache, e.g. a flat-file * cache database. This is used to implement the jar protocol handler and * to provide the stream-as-file semantics required by the classic browser * plugin API. */ const unsigned long CACHE_AS_FILE = 1 << 11; /** * When cache data is potentially out of date, it can be revalidated with * the origin server to see if the content needs to be reloaded. The * following four flags control how often this validation occurs. * These flags are commonly used for "normal" loading. Note that * the VALIDATE_HEURISTICALLY and VALIDATE_ONCE_PER_SESSION flags can be * combined to validate heuristically but no more than once per session. */ const unsigned long VALIDATE_NEVER = 1 << 12; const unsigned long VALIDATE_ALWAYS = 1 << 13; const unsigned long VALIDATE_ONCE_PER_SESSION = 1 << 14; const unsigned long VALIDATE_HEURISTICALLY = 1 << 15; /** * This flag is used to tell the webshell not to cancel the load in cases * when the channel is receiving multipart/replace document */ const unsigned long LOAD_REPLACE = 1 << 16; }; //////////////////////////////////////////////////////////////////////////////// // nsIStreamIOChannel /** * nsIStreamIOChannel specializes nsIChannel to allow a simple channel to be * constructed from an nsIStreamIO object and a URL. */ [scriptable, uuid(308362ce-0d06-11d4-986e-00c04fa0cf4a)] interface nsIStreamIOChannel : nsIChannel { void init(in nsIURI uri, in nsIStreamIO io); }; %{C++ #define NS_STREAMIOCHANNEL_CLASSNAME "Stream I/O Channel" #define NS_STREAMIOCHANNEL_CONTRACTID "@mozilla.org/network/stream-io-channel;1" #define NS_STREAMIOCHANNEL_CID \ { /* 6ddb050c-0d04-11d4-986e-00c04fa0cf4a */ \ 0x6ddb050c, \ 0x0d04, \ 0x11d4, \ {0x98, 0x6e, 0x00, 0xc0, 0x4f, 0xa0, 0xcf, 0x4a} \ } %} //////////////////////////////////////////////////////////////////////////////// /** * nsIFileChannel is an interface that allows for the initialization * of a simple nsIChannel that is constructed from a single nsIFile and * associated content type. */ [scriptable, uuid(68a26506-f947-11d3-8cda-0060b0fc14a3)] interface nsIFileChannel : nsIChannel { /** * Values for ioFlags parameters to be or'd together. * (From prio.h) */ const long NS_RDONLY = 0x01; const long NS_WRONLY = 0x02; const long NS_RDWR = 0x04; const long NS_CREATE_FILE = 0x08; const long NS_APPEND = 0x10; const long NS_TRUNCATE = 0x20; const long NS_SYNC = 0x40; const long NS_EXCL = 0x80; void init(in nsIFile file, in long ioFlags, in long perm); readonly attribute nsIFile file; attribute long ioFlags; attribute long permissions; }; %{C++ #define NS_LOCALFILECHANNEL_CLASSNAME "Local File Channel" #define NS_LOCALFILECHANNEL_CONTRACTID "@mozilla.org/network/local-file-channel;1" #define NS_LOCALFILECHANNEL_CID \ { /* 6d5b2d44-f947-11d3-8cda-0060b0fc14a3 */ \ 0x6d5b2d44, \ 0xf947, \ 0x11d3, \ {0x8c, 0xda, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \ } %} ////////////////////////////////////////////////////////////////////////////////
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ #include "nsIRequest.idl" interface nsIChannel; interface nsIRequest; interface nsISimpleEnumerator; interface nsIStreamObserver; interface nsIStreamListener; interface nsIInputStream; [scriptable, uuid(60fdf550-5392-11d3-9a97-0080c7cb1080)] interface nsILoadGroupListenerFactory : nsISupports { nsIStreamListener createLoadGroupListener(in nsIStreamListener alistener); }; /** * A load group maintains a collection of active URL requests. */ [scriptable, uuid(19845248-29ab-11d3-8cce-0060b0fc14a3)] interface nsILoadGroup : nsIRequest { void init(in nsIStreamObserver observer); /** * Accesses the default load attributes for the group, returned as * a flag word. Setting the default load attributes will cause them * to be applied to each new channel inserted into the group. */ attribute unsigned long defaultLoadAttributes; /** * Accesses the default load channel for the group. Each time a number * of request are added to a group, the DefaultLoadChannel may be set * to indicate that all of the requests are related to a particular URL. */ attribute nsIRequest defaultLoadRequest; /** * Adds a new request to the group. This will cause the default load * attributes to be applied to that request. If the request added is * the first request in the group, the group's observer's OnStartRequest * method is called. */ void addRequest(in nsIRequest request, in nsISupports ctxt); /** * Removes a request from the group. If the request removed is * the last request in the group, the group's observer's OnStopRequest * method is called. */ void removeRequest(in nsIRequest request, in nsISupports ctxt, in nsresult status, in wstring statusArg); /** * Returns the requests contained directly in this group. * Enumerator element type: nsIRequest. */ readonly attribute nsISimpleEnumerator requests; attribute nsIStreamObserver groupObserver; attribute nsILoadGroupListenerFactory groupListenerFactory; readonly attribute unsigned long activeCount; }; %{C++ #define NS_LOADGROUP_CID \ { /* e1c61582-2a84-11d3-8cce-0060b0fc14a3 */ \ 0xe1c61582, \ 0x2a84, \ 0x11d3, \ {0x8c, 0xce, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \ } %}
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ #include "nsISupports.idl" interface nsIRequest; interface nsIEventQueue; [scriptable, uuid(fd91e2e0-1481-11d3-9333-00104ba0fd40)] interface nsIStreamObserver : nsISupports { /** * Called to signify the beginning of an asynchronous request. * * @param request - request being observed * @param ctxt - user specified data passed to AsyncRead/Write */ void onStartRequest(in nsIRequest request, in nsISupports ctxt); /** * Called to signify the end of an asynchronous request. This * call is always preceded by a call to onStartRequest. * * @param request - request being observed * @param ctxt - user specified data passed to AsyncRead/Write * @param statusCode - reason for stopping (NS_OK if completed successfully) * @param statusText - human readable reason for stopping (can be NULL) */ void onStopRequest(in nsIRequest request, in nsISupports ctxt, in nsresult statusCode, in wstring statusText); }; /** * A stream observer proxy is used to ship data over to another thread specified * by the thread's event queue. The "true" stream observer's methods are * invoked on the other thread. * * This interface only provides the initialization needed after construction. Otherwise, * these objects are used simply as nsIStreamObserver's. */ [scriptable, uuid(3c9b532e-db84-4ecf-aa6a-4d38a9c4c5f0)] interface nsIStreamObserverProxy : nsIStreamObserver { /** * Initializes an nsIStreamObserverProxy. * * @param observer - receives observer notifications on the other thread * @param eventQ - may be NULL indicating the calling thread's event queue */ void init(in nsIStreamObserver observer, in nsIEventQueue eventQ); }; /** * An asynchronous stream observer is used to ship data over to another thread specified * by the thread's event queue. The receiver stream observer is then used to receive * the notifications on the other thread. * * This interface only provides the initialization needed after construction. Otherwise, * these objects are used simply as nsIStreamObservers. */ [scriptable, uuid(a28dc590-91b3-11d3-8cd9-0060b0fc14a3)] interface nsIAsyncStreamObserver : nsIStreamObserver { /** * Initializes an nsIAsyncStreamObserver. * @param eventQueue - may be null indicating the calling thread's event queue */ void init(in nsIStreamObserver receiver, in nsIEventQueue eventQueue); }; %{C++ // Generic status codes for OnStopRequest: #define NS_BINDING_SUCCEEDED NS_OK #define NS_BINDING_FAILED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 1) #define NS_BINDING_ABORTED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 2) %}
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ #include "nsIStreamObserver.idl" interface nsIRequest; interface nsIInputStream; interface nsIOutputStream; interface nsIEventQueue; /** * The nsIChannel::AsyncRead notification handler. It accepts * data from the channel, when the channel is ready to provide it. */ [scriptable, uuid(1a637020-1482-11d3-9333-00104ba0fd40)] interface nsIStreamListener : nsIStreamObserver { /** * Called when there is data to be read from the channel. * * @param request - the request returned by AsyncRead * @param ctxt - opaque parameter passed to AsyncRead * @param input - temporary input stream for reading data chunk * @param offset - current stream position (informational) * @param count - number of bytes that can be read without blocking * * @return NS_OK - if successfully read something. * @return NS_BASE_STREAM_CLOSED - if done reading data. NOTE: this is * NOT equivalent to reading zero bytes and returning NS_OK. * @return NS_BASE_STREAM_WOULD_BLOCK - if no data can be read at * this time. This implicitly calls Suspend on the channel. Call * Resume on the channel to continue the AsyncRead when more data * becomes available. * @return <other-error> - if failure. */ void onDataAvailable(in nsIRequest request, in nsISupports ctxt, in nsIInputStream input, in unsigned long offset, in unsigned long count); }; /** * A stream listener proxy is used to ship data over to another thread specified * by the thread's event queue. The "true" stream listener's methods are * invoked on the other thread. * * This interface only provides the initialization needed after construction. * Otherwise, these objects may be used as a nsIStreamListener. */ [scriptable, uuid(e400e688-6b54-4a84-8c4e-56b40281981a)] interface nsIStreamListenerProxy : nsIStreamListener { /** * Initializes an nsIStreamListenerProxy. * * @param listener - receives listener notifications on the other thread * @param eventQ - may be NULL indicating the calling thread's event queue * @param bufferSegmentSize - passing zero indicates the default * @param bufferMaxSize - passing zero indicates the default */ void init(in nsIStreamListener listener, in nsIEventQueue eventQ, in unsigned long bufferSegmentSize, in unsigned long bufferMaxSize); }; /** * A simple stream listener can be used with AsyncRead to supply data to * a output stream. */ [scriptable, uuid(a9b84f6a-0824-4278-bae6-bfca0570a26e)] interface nsISimpleStreamListener : nsIStreamListener { /** * Initialize the simple stream listener. * * @param sink - data will be read from the channel to this output stream * @param observer - optional stream observer (can be NULL) */ void init(in nsIOutputStream sink, in nsIStreamObserver observer); }; /** * An asynchronous stream listener is used to ship data over to another thread specified * by the thread's event queue. The receiver stream listener is then used to receive * the notifications on the other thread. * * This interface only provides the initialization needed after construction. Otherwise, * these objects are used simply as nsIStreamListener. */ [scriptable, uuid(1b012ade-91bf-11d3-8cd9-0060b0fc14a3)] interface nsIAsyncStreamListener : nsIStreamListener { /** * Initializes an nsIAsyncStreamListener. * @param eventQueue - may be null indicating the calling thread's event queue */ void init(in nsIStreamListener receiver, in nsIEventQueue eventQueue); };
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): */ #include "nsIStreamObserver.idl" interface nsIChannel; interface nsIInputStream; interface nsIOutputStream; interface nsIEventQueue; /** * The nsIChannel::AsyncWrite notification handler. It provides * data to the channel, when the channel is ready to accept it. */ [scriptable, uuid(d10ef7a9-b728-43d4-9c49-74172186d691)] interface nsIStreamProvider : nsIStreamObserver { /** * Called when data may be written to the channel. * * @param request - the request returned by AsyncWrite * @param ctxt - opaque parameter passed to AsyncWrite * @param output - output stream for writing data chunk * @param offset - current stream position (informational) * @param count - number of bytes that can be written without blocking * * @return NS_OK - if successfully wrote something. * @return NS_BASE_STREAM_CLOSED - if done writing data. NOTE: this is * NOT equivalent to writing zero bytes and returning NS_OK. * @return NS_BASE_STREAM_WOULD_BLOCK - if no data can be written at * this time. This implicitly calls Suspend on the channel. Call * Resume on the channel to continue the AsyncWrite when more data * becomes available. * @return <other-error> - if failure. */ void onDataWritable(in nsIRequest request, in nsISupports ctxt, in nsIOutputStream output, in unsigned long offset, in unsigned long count); }; /** * A stream provider proxy is used to ship data over to another thread specified * by the thread's event queue. The "true" stream provider's methods are * invoked on the other thread. * * This interface only provides the initialization needed after construction. * Otherwise, these objects may be used as a nsIStreamProvider. */ [scriptable, uuid(5c3b0bac-605a-49ac-880e-5c8b993f7d2b)] interface nsIStreamProviderProxy : nsIStreamProvider { /** * Initializes an nsIStreamProviderProxy. * * @param provider - receives provider notifications on the other thread. * @param eventQ - may be NULL indicating the calling thread's event queue. */ void init(in nsIStreamProvider provider, in nsIEventQueue eventQ, in unsigned long bufferSegmentSize, in unsigned long bufferMaxSize); }; /** * A simple stream provider can be used with AsyncWrite to supply data from * an existing input stream. */ [scriptable, uuid(c20bb3b9-0755-4eff-9222-3537f9e89082)] interface nsISimpleStreamProvider : nsIStreamProvider { /** * Initialize the simple stream provider. * * @param - data will be read from this input stream to the channel * @param - optional stream observer (can be NULL) */ void init(in nsIInputStream source, in nsIStreamObserver observer); };