/* DataOutputStream.java -- Writes primitive Java datatypes to streams
   Copyright (C) 1998, 2001, 2003, 2005, 2008  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
 
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.io;

/* Written using "Java Class Libraries", 2nd edition, ISBN 0-201-31002-3
 * "The Java Language Specification", ISBN 0-201-63451-1
 * Status:  Complete to version 1.1.
 */

/**
 * This class provides a mechanism for writing primitive Java datatypes
 * to an <code>OutputStream</code> in a portable way.  Data written to
 * a stream using this class can be read back in using the
 * <code>DataInputStream</code> class on any platform.
 *
 * @see DataInputStream
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Tom Tromey (tromey@cygnus.com)
 */
public class DataOutputStream extends FilterOutputStream implements DataOutput
{
  /**
   * This is the total number of bytes that have been written to the
   * stream by this object instance.
   */
  protected int written;

  /**
   * Utf8 byte buffer, used by writeUTF()
   */
  private byte[] buf;
  
  /**
   * This method initializes an instance of <code>DataOutputStream</code> to
   * write its data to the specified underlying <code>OutputStream</code>
   *
   * @param out The subordinate <code>OutputStream</code> to which this 
   * object will write
   */
  public DataOutputStream (OutputStream out)
  {
    super (out);
    written = 0;
  }

  /**
   * This method flushes any unwritten bytes to the underlying stream.
   *
   * @exception IOException If an error occurs.
   */
  public void flush () throws IOException
  {
    out.flush();
  }

  /**
   * This method returns the total number of bytes that have been written to
   * the underlying output stream so far.  This is the value of the
   * <code>written</code> instance variable
   *
   * @return The number of bytes written to the stream.
   */
  public final int size ()
  {
    return written;
  }

  /**
   * This method writes the specified byte (passed as an <code>int</code>)
   * to the underlying output stream.
   *
   * @param value The <code>byte</code> to write, passed as an <code>int</code>.
   *
   * @exception IOException If an error occurs.
   */
  public synchronized void write (int value) throws IOException
  {
    out.write (value);
    ++written;
  }

  /**
   * This method writes <code>len</code> bytes from the specified byte array
   * <code>buf</code> starting at position <code>offset</code> into the
   * buffer to the underlying output stream.
   *
   * @param buf The byte array to write from.
   * @param offset The index into the byte array to start writing from.
   * @param len The number of bytes to write.
   *
   * @exception IOException If an error occurs.
   */
  public synchronized void write (byte[] buf, int offset, int len) 
     throws IOException
  {
    out.write(buf, offset, len);
    written += len;
  }

  /**
   * This method writes a Java boolean value to an output stream.  If
   * <code>value</code> is <code>true</code>, a byte with the value of
   * 1 will be written, otherwise a byte with the value of 0 will be
   * written.
   *
   * The value written can be read using the <code>readBoolean</code>
   * method in <code>DataInput</code>.
   *
   * @param value The <code>boolean</code> value to write to the stream
   *
   * @exception IOException If an error occurs
   *
   * @see DataInput#readBoolean
   */
  public final void writeBoolean (boolean value) throws IOException
  {
    write (value ? 1 : 0);
  }

  /**
   * This method writes a Java byte value to an output stream.  The
   * byte to be written will be in the lowest 8 bits of the
   * <code>int</code> value passed.
   *
   * The value written can be read using the <code>readByte</code> or
   * <code>readUnsignedByte</code> methods in <code>DataInput</code>.
   *
   * @param value The <code>byte</code> to write to the stream, passed as 
   * the low eight bits of an <code>int</code>.
   *
   * @exception IOException If an error occurs
   *
   * @see DataInput#readByte
   * @see DataInput#readUnsignedByte
   */
  public final void writeByte (int value) throws IOException
  {
    write (value & 0xff);
  }

  /**
   * This method writes a Java short value to an output stream.  The
   * char to be written will be in the lowest 16 bits of the <code>int</code>
   * value passed.  These bytes will be written "big endian".  That is,
   * with the high byte written first in the following manner:
   * <p>
   * <code>byte0 = (byte)((value & 0xFF00) >> 8);<br>
   * byte1 = (byte)(value & 0x00FF);</code>
   * <p>
   *
   * The value written can be read using the <code>readShort</code> and
   * <code>readUnsignedShort</code> methods in <code>DataInput</code>.
   *
   * @param value The <code>short</code> value to write to the stream,
   * passed as an <code>int</code>.
   *
   * @exception IOException If an error occurs
   *
   * @see DataInput#readShort
   * @see DataInput#readUnsignedShort
   */
  public final synchronized void writeShort (int value) throws IOException
  {
    write ((byte) (0xff & (value >> 8)));
    write ((byte) (0xff & value));
  }

  /**
   * This method writes a Java char value to an output stream.  The
   * char to be written will be in the lowest 16 bits of the <code>int</code>
   * value passed.  These bytes will be written "big endian".  That is,
   * with the high byte written first in the following manner:
   * <p>
   * <code>byte0 = (byte)((value & 0xFF00) >> 8);<br>
   * byte1 = (byte)(value & 0x00FF);</code>
   * <p>
   *
   * The value written can be read using the <code>readChar</code>
   * method in <code>DataInput</code>.
   *
   * @param value The <code>char</code> value to write, 
   * passed as an <code>int</code>.
   *
   * @exception IOException If an error occurs
   *
   * @see DataInput#readChar
   */
  public final synchronized void writeChar (int value) throws IOException
  {
    write ((byte) (0xff & (value >> 8)));
    write ((byte) (0xff & value));
  }

  /**
   * This method writes a Java int value to an output stream.  The 4 bytes
   * of the passed value will be written "big endian".  That is, with
   * the high byte written first in the following manner:
   * <p>
   * <code>byte0 = (byte)((value & 0xFF000000) >> 24);<br>
   * byte1 = (byte)((value & 0x00FF0000) >> 16);<br>
   * byte2 = (byte)((value & 0x0000FF00) >> 8);<br>
   * byte3 = (byte)(value & 0x000000FF);</code>
   * <p>
   *
   * The value written can be read using the <code>readInt</code>
   * method in <code>DataInput</code>.
   *
   * @param value The <code>int</code> value to write to the stream
   *
   * @exception IOException If an error occurs
   *
   * @see DataInput#readInt
   */
  public final synchronized void writeInt (int value) throws IOException
  {
    write ((byte) (0xff & (value >> 24)));
    write ((byte) (0xff & (value >> 16)));
    write ((byte) (0xff & (value >>  8)));
    write ((byte) (0xff & value));
  }

  /**
   * This method writes a Java long value to an output stream.  The 8 bytes
   * of the passed value will be written "big endian".  That is, with
   * the high byte written first in the following manner:
   * <p>
   * <code>byte0 = (byte)((value & 0xFF00000000000000L) >> 56);<br>
   * byte1 = (byte)((value & 0x00FF000000000000L) >> 48);<br>
   * byte2 = (byte)((value & 0x0000FF0000000000L) >> 40);<br>
   * byte3 = (byte)((value & 0x000000FF00000000L) >> 32);<br>
   * byte4 = (byte)((value & 0x00000000FF000000L) >> 24);<br>
   * byte5 = (byte)((value & 0x0000000000FF0000L) >> 16);<br>
   * byte6 = (byte)((value & 0x000000000000FF00L) >> 8);<br>
   * byte7 = (byte)(value & 0x00000000000000FFL);</code>
   * <p>
   *
   * The value written can be read using the <code>readLong</code>
   * method in <code>DataInput</code>.
   *
   * @param value The <code>long</code> value to write to the stream
   *
   * @exception IOException If an error occurs
   *
   * @see DataInput#readLong
   */
  public final synchronized void writeLong (long value) throws IOException
  {
    write ((byte) (0xff & (value >> 56)));
    write ((byte) (0xff & (value>> 48)));
    write ((byte) (0xff & (value>> 40)));
    write ((byte) (0xff & (value>> 32)));
    write ((byte) (0xff & (value>> 24)));
    write ((byte) (0xff & (value>> 16)));
    write ((byte) (0xff & (value>>  8)));
    write ((byte) (0xff & value));
  }

  /**
   * This method writes a Java <code>float</code> value to the stream.  This
   * value is written by first calling the method
   * <code>Float.floatToIntBits</code>
   * to retrieve an <code>int</code> representing the floating point number,
   * then writing this <code>int</code> value to the stream exactly the same
   * as the <code>writeInt()</code> method does.
   *
   * The value written can be read using the <code>readFloat</code>
   * method in <code>DataInput</code>.
   *
   * @param value The <code>float</code> value to write to the stream
   *
   * @exception IOException If an error occurs
   *
   * @see #writeInt(int)
   * @see DataInput#readFloat
   * @see Float#floatToIntBits
   */
  public final void writeFloat (float value) throws IOException
  {
    writeInt (Float.floatToIntBits (value));
  }

  /**
   * This method writes a Java <code>double</code> value to the stream.  This
   * value is written by first calling the method
   * <code>Double.doubleToLongBits</code>
   * to retrieve an <code>long</code> representing the floating point number,
   * then writing this <code>long</code> value to the stream exactly the same
   * as the <code>writeLong()</code> method does.
   *
   * The value written can be read using the <code>readDouble</code>
   * method in <code>DataInput</code>.
   *
   * @param value The <code>double</code> value to write to the stream
   *
   * @exception IOException If an error occurs
   *
   * @see #writeLong(long)
   * @see DataInput#readDouble
   * @see Double#doubleToLongBits
   */
  public final void writeDouble (double value) throws IOException
  {
    writeLong (Double.doubleToLongBits (value));
  }

  /**
   * This method writes all the bytes in a <code>String</code> out to the
   * stream.  One byte is written for each character in the
   * <code>String</code>.
   * The high eight bits of each character are discarded, thus this
   * method is inappropriate for completely representing Unicode characters.
   *
   * @param value The <code>String</code> to write to the stream
   *
   * @exception IOException If an error occurs
   */
  public final void writeBytes (String value) throws IOException
  {
    int len = value.length();
    for (int i = 0; i < len; ++i)
      writeByte (value.charAt(i));
  }

  /**
   * This method writes all the characters of a <code>String</code> to an
   * output stream as an array of <code>char</code>'s. Each character
   * is written using the method specified in the <code>writeChar</code>
   * method.
   *
   * @param value The <code>String</code> to write to the stream
   *
   * @exception IOException If an error occurs
   *
   * @see #writeChar(char)
   */
  public final void writeChars (String value) throws IOException
  {
    int len = value.length();
    for (int i = 0; i < len; ++i)
      writeChar (value.charAt(i));
  }

  /**
   *  Calculate the length, in bytes, of a <code>String</code> in Utf8 format.
   *  This method is package-private so that <code>ObjectOutputStream</code>
   *  may use it.  The return type is long so that a long string whose
   *  Utf8 byte count is 64 bit long may be handled.
   *
   *  @param value The <code>String</code> to measure
   *  @param start String index at which to begin count
   *  @param sum Starting Utf8 byte count
   *
   */
  long getUTFlength(String value, int start, long sum)
  {
    int len = value.length();

    for (int i = start; i < len; ++i)
      {
	char c = value.charAt(i);
	if (c >= '\u0001' && c <= '\u007f')
	  sum += 1;
	else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
	  sum += 2;
	else
	  sum += 3;
      }

    return sum;
  }
  
  /**
   * This method writes a Java <code>String</code> to the stream in a modified
   * UTF-8 format.  First, two bytes are written to the stream indicating the
   * number of bytes to follow.  Note that this is the number of bytes in the
   * encoded <code>String</code> not the <code>String</code> length.  Next
   * come the encoded characters.  Each character in the <code>String</code>
   * is encoded as either one, two or three bytes.  For characters in the
   * range of <code>\u0001</code> to <\u007F>, one byte is used.  The character
   * value goes into bits 0-7 and bit eight is 0.  For characters in the range
   * of <code>\u0080</code> to <code>\u007FF</code>, two bytes are used.  Bits
   * 6-10 of the character value are encoded bits 0-4 of the first byte, with
   * the high bytes having a value of "110".  Bits 0-5 of the character value
   * are stored in bits 0-5 of the second byte, with the high bits set to
   * "10".  This type of encoding is also done for the null character
   * <code>\u0000</code>.  This eliminates any C style NUL character values
   * in the output.  All remaining characters are stored as three bytes.
   * Bits 12-15 of the character value are stored in bits 0-3 of the first
   * byte.  The high bits of the first bytes are set to "1110".  Bits 6-11
   * of the character value are stored in bits 0-5 of the second byte.  The
   * high bits of the second byte are set to "10".  And bits 0-5 of the
   * character value are stored in bits 0-5 of byte three, with the high bits
   * of that byte set to "10".
   *
   * The value written can be read using the <code>readUTF</code>
   * method in <code>DataInput</code>.
   *
   * @param value The <code>String</code> to write to the output in UTF format
   *
   * @exception IOException If an error occurs
   *
   * @see DataInput#readUTF
   */
  public final synchronized void writeUTF(String value) throws IOException
  {
    long l = getUTFlength(value, 0, 0);
    if (l > 65535)
      throw new UTFDataFormatException ();
    writeUTFShort(value, (int)l);
  }

  /**
   * This method performs the main task of <code>writeUTF</code>.
   * This method is package-private because ObjectOutputStream uses it.
   *
   * @param value The <code>String</code> to write to the output in UTF format
   *
   * @param bytelen The UTF-8 byte length of the <code>String</code>. When
   * this method is called, the expected byte length must have been calculated
   * by <code>getUTFlength</code>.
   *
   * @exception IOException If an error occurs
   *
   * @see DataInput#readUTF
   */
  final synchronized void writeUTFShort(String value, int bytelen)
    throws IOException
  {
    writeShort(bytelen);
    writeUTFBytes(value);
  }

  /**
   * This method is similar to <code>writeUTF</code>, but it writes the
   * UTF-8 byte length in 64 bits.
   * This method is not public but <code>ObjectOutputStream</code> uses it.
   *
   * @param value The <code>String</code> to write to the output in UTF format
   *
   * @param bytelen The UTF-8 byte length of the <code>String</code>. When
   * this method is called, the expected byte length must have been calculated
   * by <code>getUTFlength</code>.
   *
   * @exception IOException If an error occurs
   *
   */
  final synchronized void writeUTFLong(String value, long bytelen)
    throws IOException
  {
    writeLong(bytelen);
    writeUTFBytes(value);
  }

  /**
   * This method performes the main task of <code>writeUTF</code> and
   * <code>WriteUTFLong</code>, which is to write the UTF-8 byte
   * sequence to the output.
   *
   * @param value The <code>String</code> to write to the output in UTF format
   *
   * @exception IOException If an error occurs
   *
   */
  private final synchronized void writeUTFBytes(String value)
    throws IOException
  {
    int len = value.length();
    int i = 0;
    int pos = 0;

    if (buf == null)
      buf = new byte[512];
    
    do
      {
	while (i < len && pos < buf.length - 3)
	  {
	    char c = value.charAt(i++);
	    if (c >= '\u0001' && c <= '\u007f')
              buf[pos++] = (byte) c;
	    else if (c == '\u0000' || (c >= '\u0080' && c <= '\u07ff'))
	      {
		buf[pos++] = (byte) (0xc0 | (0x1f & (c >> 6)));
		buf[pos++] = (byte) (0x80 | (0x3f & c));
	      }
	    else
	      {
		// JSL says the first byte should be or'd with 0xc0, but
		// that is a typo.  Unicode says 0xe0, and that is what is
		// consistent with DataInputStream.
		buf[pos++] = (byte) (0xe0 | (0x0f & (c >> 12)));
		buf[pos++] = (byte) (0x80 | (0x3f & (c >> 6)));
		buf[pos++] = (byte) (0x80 | (0x3f & c));
	      }
	  }
	write(buf, 0, pos);
	pos = 0;
     }
    while (i < len);
  }

} // class DataOutputStream

