/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (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.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
==================================================================== */

package org.apache.poi.poifs.filesystem;

import java.io.*;

import java.util.*;

/**
 * This class provides a wrapper over an OutputStream so that Document
 * writers can't accidently go over their size limits
 *
 * @author Marc Johnson (mjohnson at apache dot org)
 */

public final class DocumentOutputStream extends OutputStream {
    private final OutputStream _stream;
    private final int          _limit;
    private int          _written;

    /**
     * Create a DocumentOutputStream
     *
     * @param stream the OutputStream to which the data is actually
     *               read
     * @param limit the maximum number of bytes that can be written
     */
    DocumentOutputStream(OutputStream stream, int limit) {
        _stream  = stream;
        _limit   = limit;
        _written = 0;
    }

    /**
     * Writes the specified byte to this output stream. The general
     * contract for write is that one byte is written to the output
     * stream. The byte to be written is the eight low-order bits of
     * the argument b. The 24 high-order bits of b are ignored.
     *
     * @param b the byte.
     * @exception IOException if an I/O error occurs. In particular,
     *                        an IOException may be thrown if the
     *                        output stream has been closed, or if the
     *                        writer tries to write too much data.
     */
    public void write(int b)
        throws IOException
    {
        limitCheck(1);
        _stream.write(b);
    }

    /**
     * Writes b.length bytes from the specified byte array
     * to this output stream.
     *
     * @param b the data.
     * @exception IOException if an I/O error occurs.
     */
    public void write(byte b[])
        throws IOException
    {
        write(b, 0, b.length);
    }

    /**
     * Writes len bytes from the specified byte array starting at
     * offset off to this output stream.  The general contract for
     * write(b, off, len) is that some of the bytes in the array b are
     * written to the output stream in order; element b[off] is the
     * first byte written and b[off+len-1] is the last byte written by
     * this operation.<p>
     * If b is null, a NullPointerException is thrown.<p>
     * If off is negative, or len is negative, or off+len is greater
     * than the length of the array b, then an
     * IndexOutOfBoundsException is thrown.
     *
     * @param b the data.
     * @param off the start offset in the data.
     * @param len the number of bytes to write.
     * @exception IOException if an I/O error occurs. In particular,
     *                        an IOException</code> is thrown if the
     *                        output stream is closed or if the writer
     *                        tries to write too many bytes.
     */
    public void write(byte b[], int off, int len)
        throws IOException
    {
        limitCheck(len);
        _stream.write(b, off, len);
    }

    /**
     * Flushes this output stream and forces any buffered output bytes
     * to be written out.
     *
     * @exception IOException if an I/O error occurs.
     */
    public void flush()
        throws IOException
    {
        _stream.flush();
    }

    /**
     * Closes this output stream and releases any system resources
     * associated with this stream. The general contract of close is
     * that it closes the output stream. A closed stream cannot
     * perform output operations and cannot be reopened.
     *
     * @exception IOException if an I/O error occurs.
     */
    public void close() {

        // ignore this call
    }

    /**
     * write the rest of the document's data (fill in at the end)
     *
     * @param totalLimit the actual number of bytes the corresponding
     *                   document must fill
     * @param fill the byte to fill remaining space with
     *
     * @exception IOException on I/O error
     */
    void writeFiller(int totalLimit, byte fill)
        throws IOException
    {
        if (totalLimit > _written)
        {
            byte[] filler = new byte[ totalLimit - _written ];

            Arrays.fill(filler, fill);
            _stream.write(filler);
        }
    }

    private void limitCheck(int toBeWritten)
        throws IOException
    {
        if ((_written + toBeWritten) > _limit)
        {
            throw new IOException("tried to write too much data");
        }
        _written += toBeWritten;
    }
}
