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

/**
 * Defines an interface for classes that are able to write typed data to some
 * target. Typically, this data can be read in by a class which implements
 * DataInput. Types that can be written include byte, 16-bit short, 32-bit int,
 * 32-bit float, 64-bit long, 64-bit double, byte strings, and {@link DataInput
 * MUTF-8} encoded strings.
 * 
 * @see DataOutputStream
 * @see RandomAccessFile
 */
public interface DataOutput {

    /**
     * Writes the entire contents of the byte array {@code buffer} to this
     * stream.
     * 
     * @param buffer
     *            the buffer to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readFully(byte[])
     * @see DataInput#readFully(byte[], int, int)
     */
    public abstract void write(byte[] buffer) throws IOException;

    /**
     * Writes {@code count} bytes from the byte array {@code buffer} starting at
     * offset {@code index}.
     * 
     * @param buffer
     *            the buffer to write.
     * @param offset
     *            the index of the first byte in {@code buffer} to write.
     * @param count
     *            the number of bytes from the {@code buffer} to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readFully(byte[])
     * @see DataInput#readFully(byte[], int, int)
     */
    public abstract void write(byte buffer[], int offset, int count)
            throws IOException;

    /**
     * Writes the specified 8-bit byte.
     * 
     * @param oneByte
     *            the byte to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readByte()
     */
    public abstract void write(int oneByte) throws IOException;

    /**
     * Writes the specified boolean.
     * 
     * @param val
     *            the boolean value to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readBoolean()
     */
    public abstract void writeBoolean(boolean val) throws IOException;

    /**
     * Writes the specified 8-bit byte.
     * 
     * @param val
     *            the byte value to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readByte()
     * @see DataInput#readUnsignedByte()
     */
    public abstract void writeByte(int val) throws IOException;

    /**
     * Writes the low order 8-bit bytes from the specified string.
     * 
     * @param str
     *            the string containing the bytes to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readFully(byte[])
     * @see DataInput#readFully(byte[],int,int)
     */
    public abstract void writeBytes(String str) throws IOException;

    /**
     * Writes the specified 16-bit character. Only the two least significant
     * bytes of the integer {@code oneByte} are written, with the higher one
     * written first. This represents the Unicode value of the char.
     * 
     * @param val
     *            the character to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readChar()
     */
    public abstract void writeChar(int val) throws IOException;

    /**
     * Writes the 16-bit characters contained in {@code str}.
     * 
     * @param str
     *            the string that contains the characters to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readChar()
     */
    public abstract void writeChars(String str) throws IOException;

    /**
     * Writes the specified 64-bit double. The resulting output is the eight
     * bytes returned by {@link Double#doubleToLongBits(double)}.
     * 
     * @param val
     *            the double to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readDouble()
     */
    public abstract void writeDouble(double val) throws IOException;

    /**
     * Writes the specified 32-bit float. The resulting output is the four bytes
     * returned by {@link Float#floatToIntBits(float)}.
     * 
     * @param val
     *            the float to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readFloat()
     */
    public abstract void writeFloat(float val) throws IOException;

    /**
     * Writes the specified 32-bit int. The resulting output is the four bytes,
     * highest order first, of {@code val}.
     * 
     * @param val
     *            the int to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readInt()
     */
    public abstract void writeInt(int val) throws IOException;

    /**
     * Writes the specified 64-bit long. The resulting output is the eight
     * bytes, highest order first, of {@code val}.
     * 
     * @param val
     *            the long to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readLong()
     */
    public abstract void writeLong(long val) throws IOException;

    /**
     * Writes the specified 16-bit short. Only the lower two bytes of {@code
     * val} are written with the higher one written first.
     * 
     * @param val
     *            the short to write.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readShort()
     * @see DataInput#readUnsignedShort()
     */
    public abstract void writeShort(int val) throws IOException;

    /**
     * Writes the specified string encoded in {@link DataInput modified UTF-8}.
     * 
     * @param str
     *            the string to write encoded in {@link DataInput modified UTF-8}.
     * @throws IOException
     *             if an I/O error occurs while writing.
     * @see DataInput#readUTF()
     */
    public abstract void writeUTF(String str) throws IOException;
}
