package io;

import java.io.*;


/**
 *  For writing binary streams to be read on a
 *  machine that uses a little-endian scheme.
 *
 *  For example, C under DOS/Windows uses a little-endian scheme 
 *  (i.e., LSB first).
 *
 *  @author  Prof. David Bernstein, James Madison University
 *  @version 1.0
 */
public class LittleEndianOutputStream 
{
    protected byte[]       b1, b2, b4;
    protected OutputStream out;


    /**
     * Construct a new LittleEndianOutputStream
     *
     * @param in   The OutputStream to use
     */
    public LittleEndianOutputStream(OutputStream out)
    {
	this.out = out;

	b1 = new byte[1];
	b2 = new byte[2];
	b4 = new byte[4];
    }


    /**
     * Closes this output stream
     */
    public void close() throws IOException
    {
	out.close();
    }


    /**
     * Writes a 1-byte integer
     *
     * @param   i  The int to write
     */
    public void writeInteger1(int i) throws IOException
    {
	b1[0] = (byte)i;

	out.write(b1,0,1);
    }


    /**
     * Writes a 2-byte integer
     *
     * @param   i  The int to write
     */
    public void writeInteger2(int i) throws IOException
    {
	b2[0] = (byte)i;        // LSB
	b2[1] = (byte)(i >> 8); // MSB

	out.write(b2,0,2);
    }


    /**
     * Writes a 4-byte integer
     *
     * @param   i  The int to write
     */
    public void writeInteger4(int i) throws IOException
    {
	b4[0] = (byte)i;         // LSB
	b4[1] = (byte)(i >> 8);
	b4[2] = (byte)(i >> 16);
	b4[3] = (byte)(i >> 24); // MSB

	out.write(b4,0,4);
    }


    /**
     * Writes an 8-byte integer
     *
     * @param   l The long to write
     */
    public void writeInteger8(long l) throws IOException
    {
	b4[0] = (byte)l;         // LSB
	b4[1] = (byte)(l >> 8);
	b4[2] = (byte)(l >> 16);
	b4[3] = (byte)(l >> 24);
	b4[4] = (byte)(l >> 32);
	b4[5] = (byte)(l >> 40);
	b4[6] = (byte)(l >> 48);
	b4[7] = (byte)(l >> 56); // MSB

	out.write(b4,0,4);
    }


    /**
     * Writes a 4-byte real number
     *
     * @param   f  The float to write
     */
    public void writeReal4(float f) throws IOException
    {
	writeInteger4(Float.floatToIntBits(f));
    }


    /**
     * Writes an 8-byte real number
     *
     * @param   d The double to write
     */
    public void writeReal8(double d) throws IOException
    {
	writeInteger8(Double.doubleToLongBits(d));
    }

}
