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

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

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

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

};


/**
 * 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 group,
              in nsIURI originalURI);
};

%{C++

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

%}
