001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.commons.crypto.stream.output;
019
020import java.io.IOException;
021import java.io.OutputStream;
022import java.nio.ByteBuffer;
023
024/**
025 * The StreamOutput class takes a {@code OutputStream} object and wraps it
026 * as {@code Output} object acceptable by {@code CryptoOutputStream}
027 * as the output target.
028 */
029public class StreamOutput implements Output {
030    private final byte[] buf;
031    private final int bufferSize;
032    private final OutputStream out;
033
034    /**
035     * Constructs a {@link org.apache.commons.crypto.stream.output.StreamOutput}
036     * .
037     *
038     * @param out the OutputStream object.
039     * @param bufferSize the buffersize.
040     */
041    public StreamOutput(final OutputStream out, final int bufferSize) {
042        this.out = out;
043        this.bufferSize = bufferSize;
044        buf = new byte[bufferSize];
045    }
046
047    /**
048     * Overrides the
049     * {@link org.apache.commons.crypto.stream.output.Output#write(ByteBuffer)}.
050     * Writes a sequence of bytes to this output from the given buffer.
051     *
052     * @param src The buffer from which bytes are to be retrieved.
053     *
054     * @return The number of bytes written, possibly zero.
055     * @throws IOException if an I/O error occurs.
056     */
057    @Override
058    public int write(final ByteBuffer src) throws IOException {
059        final int len = src.remaining();
060
061        int remaining = len;
062        while (remaining > 0) {
063            final int n = Math.min(remaining, bufferSize);
064            src.get(buf, 0, n);
065            out.write(buf, 0, n);
066            remaining = src.remaining();
067        }
068
069        return len;
070    }
071
072    /**
073     * Overrides the {@link Output#flush()}. Flushes this output and forces any
074     * buffered output bytes to be written out if the under layer output method
075     * support.
076     *
077     * @throws IOException if an I/O error occurs.
078     */
079    @Override
080    public void flush() throws IOException {
081        out.flush();
082    }
083
084    /**
085     * Overrides the {@link Output#close()}. Closes this output and releases any
086     * system resources associated with the under layer output.
087     *
088     * @throws IOException if an I/O error occurs.
089     */
090    @Override
091    public void close() throws IOException {
092        out.close();
093    }
094
095    /**
096     * Gets the output stream.
097     *
098     * @return the output stream.
099     */
100    protected OutputStream getOut() {
101        return out;
102    }
103}