/* -*- 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"
interface nsIOutputStream;
interface nsIOutputStreamObserver;
interface nsIInputStream;

%{C++
/**
 * The signature for the reader function passed to WriteSegment. This 
 * specifies where the data should come from that gets written into the buffer.
 * Implementers should return the following:
 * @return NS_OK and readCount > 0 - if successfully read something
 * @return NS_OK and readCount == 0 - if no more to read (EOF)
 * @return NS_BASE_STREAM_WOULD_BLOCK - if there is currently no data (in
 *   a non-blocking mode)
 * @return <other-error> - on failure
 */
typedef NS_CALLBACK(nsReadSegmentFun)(nsIOutputStream* out,
                                      void* closure,
                                      char* toRawSegment,
                                      PRUint32 fromOffset,
                                      PRUint32 count,
                                      PRUint32 *readCount);
%}

native nsReadSegmentFun(nsReadSegmentFun);

[scriptable, uuid(0d0acd2a-61b4-11d4-9877-00c04fa0cf4a)]
interface nsIOutputStream : nsISupports
{
    /** 
     * Closes the stream. 
     */
    void close();

    /**
     * Flushes the stream.
     */
    void flush();

    /** Write data into the stream.
     *  @param aBuf the buffer from which the data is read
     *  @param aCount the maximum number of bytes to write
     *  @return aWriteCount out parameter to hold the number of
     *         bytes written. if an error occurs, the writecount
     *         is undefined
     */
    unsigned long write(in string buf, in unsigned long count);

    /**
     * Writes data into the stream from an input stream.
     * Implementer's note: This method is defined by this interface in order
     * to allow the output stream to efficiently copy the data from the input
     * stream into its internal buffer (if any). If this method was provide
     * as an external facility, a separate char* buffer would need to be used
     * in order to call the output stream's other Write method.
     * @param fromStream the stream from which the data is read
     * @param count the maximun number of bytes to write
     * @return aWriteCount out parameter to hold the number of
     *         bytes written. if an error occurs, the writecount
     *         is undefined
     */
    unsigned long writeFrom(in nsIInputStream inStr,
                            in unsigned long count);

    /**
     * Low-level write method that has access to the stream's underlying buffer. The
     * reader function may be called multiple times for segmented buffers.
     */
    [noscript] unsigned long writeSegments(in nsReadSegmentFun reader,
                                           in voidPtr closure,
                                           in unsigned long count);
    /**
     * Set this attribute to put the stream in non-blocking mode.
     */
    attribute boolean nonBlocking;

    /**
     * Allows users to set an observer on an output stream to receive notifications
     * about the producer writing data into the output stream, or filling the buffer.
     * This is necessary for non-blocking streams so that the consumer can suspend
     * itself until more data is available.
     */
    attribute nsIOutputStreamObserver observer;
};

[scriptable, uuid(12314194-61b4-11d4-9877-00c04fa0cf4a)]
interface nsIOutputStreamObserver : nsISupports
{
    /**
     * Called when the output stream's producer has written more data into the stream.
     */
    void onWrite(in nsIOutputStream inStr, 
                 in unsigned long amount);

    /**
     * Called when the stream's underlying buffer becomes full.
     */
    void onFull(in nsIOutputStream inStr);
};
