/* ByteBuffer.java -- 
   Copyright (C) 2002, 2003, 2004 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.nio;

/**
 * @since 1.4
 */
public abstract class ByteBuffer extends Buffer
  implements Comparable
{
  ByteOrder endian = ByteOrder.BIG_ENDIAN;

  int array_offset;
  byte[] backing_buffer;

  ByteBuffer (int capacity, int limit, int position, int mark)
  {
    super (capacity, limit, position, mark);
  }

  /**
   * Allocates a new direct byte buffer.
   */ 
  public static ByteBuffer allocateDirect (int capacity)
  {
    return DirectByteBufferImpl.allocate (capacity);
  }

  /**
   * Allocates a new <code>ByteBuffer</code> object with a given capacity.
   */
  public static ByteBuffer allocate (int capacity)
  {
    return wrap(new byte[capacity], 0, capacity);
  }

  /**
   * Wraps a <code>byte</code> array into a <code>ByteBuffer</code>
   * object.
   *
   * @exception IndexOutOfBoundsException If the preconditions on the offset
   * and length parameters do not hold
   */
  public static final ByteBuffer wrap (byte[] array, int offset, int length)
  {
    // FIXME: In GCJ and other implementations where arrays may not
    // move we might consider, at least when offset==0:
    // return new DirectByteBufferImpl(array,
    //                                 address_of_data(array) + offset,
    //                                 length, length, 0, false);
    // This may be more efficient, mainly because we can then use the
    // same logic for all ByteBuffers.

    return new ByteBufferImpl (array, 0, array.length, offset + length, offset, -1, false);
  }

  /**
   * Wraps a <code>byte</code> array into a <code>ByteBuffer</code>
   * object.
   */
  public static final ByteBuffer wrap (byte[] array)
  {
    return wrap (array, 0, array.length);
  }
  
  /**
   * This method transfers <code>byte</code>s from this buffer into the given
   * destination array. Before the transfer, it checks if there are fewer than
   * length <code>byte</code>s remaining in this buffer.
   *
   * @param dst The destination array
   * @param offset The offset within the array of the first <code>byte</code>
   * to be written; must be non-negative and no larger than dst.length.
   * @param length The maximum number of bytes to be written to the given array;
   * must be non-negative and no larger than dst.length - offset.
   *
   * @exception BufferUnderflowException If there are fewer than length
   * <code>byte</code>s remaining in this buffer.
   * @exception IndexOutOfBoundsException If the preconditions on the offset
   * and length parameters do not hold.
   */
  public ByteBuffer get (byte[] dst, int offset, int length)
  {
    checkArraySize(dst.length, offset, length);
    checkForUnderflow(length);

    for (int i = offset; i < offset + length; i++)
      {
        dst [i] = get ();
      }

    return this;
  }

  /**
   * This method transfers <code>byte</code>s from this buffer into the given
   * destination array.
   *
   * @param dst The byte array to write into.
   *
   * @exception BufferUnderflowException If there are fewer than dst.length
   * <code>byte</code>s remaining in this buffer.
   */
  public ByteBuffer get (byte[] dst)
  {
    return get (dst, 0, dst.length);
  }

  /**
   * Writes the content of the the <code>ByteBUFFER</code> src
   * into the buffer. Before the transfer, it checks if there is fewer than
   * <code>src.remaining()</code> space remaining in this buffer.
   *
   * @param src The source data.
   *
   * @exception BufferOverflowException If there is insufficient space in this
   * buffer for the remaining <code>byte</code>s in the source buffer.
   * @exception IllegalArgumentException If the source buffer is this buffer.
   * @exception ReadOnlyBufferException If this buffer is read-only.
   */
  public ByteBuffer put (ByteBuffer src)
  {
    if (src == this)
      throw new IllegalArgumentException ();

    checkForOverflow(src.remaining());

    if (src.remaining () > 0)
      {
        byte[] toPut = new byte [src.remaining ()];
        src.get (toPut);
        put (toPut);
      }

    return this;
  }

  /**
   * Writes the content of the the <code>byte array</code> src
   * into the buffer. Before the transfer, it checks if there is fewer than
   * length space remaining in this buffer.
   *
   * @param src The array to copy into the buffer.
   * @param offset The offset within the array of the first byte to be read;
   * must be non-negative and no larger than src.length.
   * @param length The number of bytes to be read from the given array;
   * must be non-negative and no larger than src.length - offset.
   * 
   * @exception BufferOverflowException If there is insufficient space in this
   * buffer for the remaining <code>byte</code>s in the source array.
   * @exception IndexOutOfBoundsException If the preconditions on the offset
   * and length parameters do not hold
   * @exception ReadOnlyBufferException If this buffer is read-only.
   */
  public ByteBuffer put (byte[] src, int offset, int length)
  {
    checkArraySize(src.length, offset, length);
    checkForOverflow(length);

    for (int i = offset; i < offset + length; i++)
      put (src [i]);

    return this;
  }

  /**
   * Writes the content of the the <code>byte array</code> src
   * into the buffer.
   *
   * @param src The array to copy into the buffer.
   * 
   * @exception BufferOverflowException If there is insufficient space in this
   * buffer for the remaining <code>byte</code>s in the source array.
   * @exception ReadOnlyBufferException If this buffer is read-only.
   */
  public final ByteBuffer put (byte[] src)
  {
    return put (src, 0, src.length);
  }

  /**
   * Tells whether ot not this buffer is backed by an accessible
   * <code>byte</code> array.
   */
  public final boolean hasArray ()
  {
    return (backing_buffer != null
            && !isReadOnly ());
  }

  /**
   * Returns the <code>byte</code> array that backs this buffer.
   *
   * @exception ReadOnlyBufferException If this buffer is read-only.
   * @exception UnsupportedOperationException If this buffer is not backed
   * by an accessible array.
   */
  public final byte[] array ()
  {
    if (backing_buffer == null)
      throw new UnsupportedOperationException ();

    checkIfReadOnly();
    
    return backing_buffer;
  }

  /**
   * Returns the offset within this buffer's backing array of the first element.
   *
   * @exception ReadOnlyBufferException If this buffer is read-only.
   * @exception UnsupportedOperationException If this buffer is not backed
   * by an accessible array.
   */
  public final int arrayOffset ()
  {
    if (backing_buffer == null)
      throw new UnsupportedOperationException ();

    checkIfReadOnly();
    
    return array_offset;
  }

  /**
   * Calculates a hash code for this buffer.
   *
   * This is done with <code>int</code> arithmetic,
   * where ** represents exponentiation, by this formula:<br>
   * <code>s[position()] + 31 + (s[position()+1] + 30)*31**1 + ... +
   * (s[limit()-1]+30)*31**(limit()-1)</code>.
   * Where s is the buffer data. Note that the hashcode is dependent
   * on buffer content, and therefore is not useful if the buffer
   * content may change.
   *
   * @return the hash code
   */
  public int hashCode ()
  {
    int hashCode = get(position()) + 31;
    int multiplier = 1;
    for (int i = position() + 1; i < limit(); ++i)
      {
	  multiplier *= 31;
	  hashCode += (get(i) + 30)*multiplier;
      }
    return hashCode;
  }

  /**
   * Checks if this buffer is equal to obj.
   */
  public boolean equals (Object obj)
  {
    if (obj instanceof ByteBuffer)
      {
        return compareTo (obj) == 0;
      }

    return false;
  }

  /**
   * Compares two <code>ByteBuffer</code> objects.
   *
   * @exception ClassCastException If obj is not an object derived from
   * <code>ByteBuffer</code>.
   */
  public int compareTo (Object obj)
  {
    ByteBuffer other = (ByteBuffer) obj;

    int num = Math.min(remaining(), other.remaining());
    int pos_this = position();
    int pos_other = other.position();
    
    for (int count = 0; count < num; count++)
      {
        byte a = get(pos_this++);
	byte b = other.get(pos_other++);
      	 
	if (a == b)
	  continue;
      	   
	if (a < b)
	  return -1;
      	   
	return 1;
      }
      
    return remaining() - other.remaining();
  }

  /**
   * Returns the byte order of this buffer.
   */  
  public final ByteOrder order ()
  {
    return endian;
  }
  
  /**
   * Modifies this buffer's byte order.
   */
  public final ByteBuffer order (ByteOrder endian)
  {
    this.endian = endian;
    return this;
  }
  
  /**
   * Reads the <code>byte</code> at this buffer's current position,
   * and then increments the position.
   *
   * @exception BufferUnderflowException If there are no remaining
   * <code>byte</code>s in this buffer.
   */
  public abstract byte get ();

  /**
   * Writes the <code>byte</code> at this buffer's current position,
   * and then increments the position.
   *
   * @exception BufferOverflowException If there no remaining 
   * <code>byte</code>s in this buffer.
   * @exception ReadOnlyBufferException If this buffer is read-only.
   */
  public abstract ByteBuffer put (byte b);

  /**
   * Absolute get method.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit.
   */
  public abstract byte get (int index);
  
  /**
   * Absolute put method.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit.
   * @exception ReadOnlyBufferException If this buffer is read-only.
   */
  public abstract ByteBuffer put (int index, byte b);

  /**
   * Compacts this buffer.
   * 
   * @exception ReadOnlyBufferException If this buffer is read-only.
   */
  public abstract ByteBuffer compact ();

  void shiftDown (int dst_offset, int src_offset, int count)
  {
    for (int i = 0; i < count; i++)
      put(dst_offset + i, get(src_offset + i));
  }

  /**
   * Tells whether or not this buffer is direct.
   */
  public abstract boolean isDirect ();

  /**
   * Creates a new <code>ByteBuffer</code> whose content is a shared
   * subsequence of this buffer's content.
   */
  public abstract ByteBuffer slice ();

  /**
   * Creates a new <code>ByteBuffer</code> that shares this buffer's
   * content.
   */
  public abstract ByteBuffer duplicate ();

  /**
   * Creates a new read-only <code>ByteBuffer</code> that shares this
   * buffer's content.
   */
  public abstract ByteBuffer asReadOnlyBuffer ();
 
  /**
   * Creates a view of this byte buffer as a short buffer.
   */
  public abstract ShortBuffer asShortBuffer ();
  
  /**
   * Creates a view of this byte buffer as a char buffer.
   */
  public abstract CharBuffer asCharBuffer ();
  
  /**
   * Creates a view of this byte buffer as an integer buffer.
   */
  public abstract IntBuffer asIntBuffer ();
  
  /**
   * Creates a view of this byte buffer as a long buffer.
   */
  public abstract LongBuffer asLongBuffer ();
  
  /**
   * Creates a view of this byte buffer as a float buffer.
   */
  public abstract FloatBuffer asFloatBuffer ();
  
  /**
   * Creates a view of this byte buffer as a double buffer.
   */
  public abstract DoubleBuffer asDoubleBuffer ();

  /**
   * Relative get method for reading a character value.
   *
   * @exception BufferUnderflowException  If there are fewer than two bytes
   * remaining in this buffer.
   */
  public abstract char getChar ();
  
  /**
   * Relative put method for writing a character value.
   *
   * @exception BufferOverflowException If this buffer's current position is
   * not smaller than its limit.
   */
  public abstract ByteBuffer putChar (char value);
  
  /**
   * Absolute get method for reading a character value.
   *
   * @exception IndexOutOfBoundsException If there are fewer than two bytes
   * remaining in this buffer
   */
  public abstract char getChar (int index);
  
  /**
   * Absolute put method for writing a character value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus one.
   */
  public abstract ByteBuffer putChar (int index, char value);
  
  /**
   * Relative get method for reading a short value.
   *
   * @exception BufferUnderflowException If index is negative or not smaller
   * than the buffer's limit, minus one.
   */
  public abstract short getShort ();
  
  /**
   * Relative put method for writing a short value.
   *
   * @exception BufferOverflowException If this buffer's current position is
   * not smaller than its limit.
   */
  public abstract ByteBuffer putShort (short value);
  
  /**
   * Absolute get method for reading a short value.
   *
   * @exception IndexOutOfBoundsException If there are fewer than two bytes
   * remaining in this buffer
   */
  public abstract short getShort (int index);
 
  /**
   * Absolute put method for writing a short value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus one.
   */
  public abstract ByteBuffer putShort (int index, short value);
  
  /**
   * Relative get method for reading an integer value.
   *
   * @exception BufferUnderflowException If there are fewer than four bytes
   * remaining in this buffer.
   */
  public abstract int getInt ();
  
  /**
   * Relative put method for writing an integer value.
   *
   * @exception BufferOverflowException If this buffer's current position is
   * not smaller than its limit.
   */
  public abstract ByteBuffer putInt (int value);
  
  /**
   * Absolute get method for reading an integer value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus three.
   */
  public abstract int getInt (int index);
  
  /**
   * Absolute put method for writing an integer value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus three.
   */
  public abstract ByteBuffer putInt (int index, int value);
  
  /**
   * Relative get method for reading a long value.
   *
   * @exception BufferUnderflowException If there are fewer than eight bytes
   * remaining in this buffer.
   */
  public abstract long getLong ();
  
  /**
   * Relative put method for writing a long value.
   *
   * @exception BufferOverflowException If this buffer's current position is
   * not smaller than its limit.
   */
  public abstract ByteBuffer putLong (long value);
  
  /**
   * Absolute get method for reading a long value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus seven.
   */
  public abstract long getLong (int index);
  
  /**
   * Absolute put method for writing a float value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus seven.
   */
  public abstract ByteBuffer putLong (int index, long value);
  
  /**
   * Relative get method for reading a float value.
   *
   * @exception BufferUnderflowException If there are fewer than four bytes
   * remaining in this buffer.
   */
  public abstract float getFloat ();
  
  /**
   * Relative put method for writing a float value.
   *
   * @exception BufferOverflowException If there are fewer than four bytes
   * remaining in this buffer.
   */
  public abstract ByteBuffer putFloat (float value);
  
  /**
   * Absolute get method for reading a float value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus three.
   */
  public abstract float getFloat (int index);
  
  /**
   * Relative put method for writing a float value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus three.
   */
  public abstract ByteBuffer putFloat (int index, float value);
  
  /**
   * Relative get method for reading a double value.
   *
   * @exception BufferUnderflowException If there are fewer than eight bytes
   * remaining in this buffer.
   */
  public abstract double getDouble ();
  
  /**
   * Relative put method for writing a double value.
   *
   * @exception BufferOverflowException If this buffer's current position is
   * not smaller than its limit.
   */
  public abstract ByteBuffer putDouble (double value);
  
  /**
   * Absolute get method for reading a double value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus seven.
   */
  public abstract double getDouble (int index);
  
  /**
   * Absolute put method for writing a double value.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit, minus seven.
   */
  public abstract ByteBuffer putDouble (int index, double value);

  /**
   * Returns a string summarizing the state of this buffer.
   */
  public String toString ()
  {
    return getClass ().getName () +
	    "[pos=" + position () +
	    " lim=" + limit () +
	    " cap=" + capacity () + "]";
  }
}
