/* -*- 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 nsIURI;
interface nsIInputStream;
interface nsIOutputStream;
interface nsIStreamObserver;
interface nsIStreamListener;
interface nsILoadGroup;
interface nsIInterfaceRequestor;

typedef unsigned long nsLoadFlags;

/**
 * nsIChannel is the abstract base class for transports and URLs.
 * It's abstract in that it doesn't provide a means to specify the
 * location/destination of the data being accessed. 
 */
[scriptable, uuid(2d905684-8b5c-11d3-8cd9-0060b0fc14a3)]
interface nsIChannel : nsIRequest
{
    /**
     * Returns the original URL used to construct the channel.
     */
    readonly attribute nsIURI originalURI;

    /**
     * Returns the URL to which the channel currently refers.
     */
    readonly attribute nsIURI URI;

    /**
     * Opens a blocking input stream to the URL's specified source.
     * @param startPosition - The offset from the start of the data
     *   from which to read.
     * @param readCount - The number of bytes to read. If -1, everything
     *   up to the end of the data is read. If greater than the end of 
     *   the data, the amount available is returned in the stream.
     */
    nsIInputStream openInputStream(in unsigned long startPosition,
                                   in long readCount);

    /**
     * Opens a blocking output stream to the URL's specified destination.
     * @param startPosition - The offset from the start of the data
     *   from which to begin writing.
     */
    nsIOutputStream openOutputStream(in unsigned long startPosition);

    /**
     * Opens the channel asynchronously. The nsIStreamObserver's OnStartRequest
     * method is called back when the channel actually becomes open, providing 
     * the content type. Its OnStopRequest method is called when the channel
     * becomes closed.
     */
    void asyncOpen(in nsIStreamObserver observer, 
                   in nsISupports ctxt);

    /**
     * Reads asynchronously from the URL's specified source. Notifications
     * are provided to the stream listener on the thread of the specified
     * event queue.
     * The startPosition argument designates the offset in the source where
     * the data will be read.
     * If the readCount == -1 then all the available data is delivered to
     * the stream listener.
     */
    void asyncRead(in unsigned long startPosition,
                   in long readCount,
                   in nsISupports ctxt,
                   in nsIStreamListener listener);

    /**
     * Writes asynchronously to the URL's specified destination. Notifications
     * are provided to the stream observer on the thread of the specified
     * event queue.
     * The startPosition argument designates the offset in the destination where
     * the data will be written.
     * If the writeCount == -1, then all the available data in the input
     * stream is written.
     */
    void asyncWrite(in nsIInputStream fromStream,
                    in unsigned long startPosition,
                    in long writeCount,
                    in nsISupports ctxt,
                    in nsIStreamObserver observer);

    /**
     * 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.
     */
    const unsigned long LOAD_NORMAL     = 0;      /* no special load attributes -- use defaults */
    const unsigned long LOAD_BACKGROUND = 1 << 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_DOCUMENT_URI = 1 << 1;
    //
    // 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;
    

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

    /**
     * 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 assiciated with the channel if available.
     * If the length is unknown then -1 is returned.
     */
    readonly attribute long contentLength;

    /**
     * Accesses the owner corresponding to the entity that is 
     * responsible for this channel. Used by security code to grant
     * or diminish privileges to mobile code loaded from this channel. 
     */
    attribute nsISupports owner;

    /**
     * Accesses the load group in which the channel is a currently a member.
     */
    attribute nsILoadGroup loadGroup;

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

};


/**
 * nsIInputStreamChannel is an interface that allows for the initialization
 * of a simple nsIChannel that is constructed from a single input stream and
 * associated content type. Input stream channels only allow the input stream
 * to be accessed, not the output stream.
 */
[scriptable, uuid(bfbf843a-8b89-11d3-8cd9-0060b0fc14a3)]
interface nsIInputStreamChannel : nsIChannel
{
    void init(in nsIURI uri,
              in string contentType, 
              in long contentLength,
              in nsIInputStream inStr,
              in nsILoadGroup aLoadGroup,
              in nsIInterfaceRequestor notificationCallbacks,
              in nsLoadFlags loadAttributes,
              in nsIURI originalURI,
              in unsigned long bufferSegmentSize,
              in unsigned long bufferMaxSize);
};

%{C++

#define NS_INPUTSTREAMCHANNEL_CID                    \
{ /* 436d84f8-8b8a-11d3-8cd9-0060b0fc14a3 */         \
    0x436d84f8,                                      \
    0x8b8a,                                          \
    0x11d3,                                          \
    {0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
}

%}
