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

/**
 * This is a Heap memory implementation
 */
final class ByteBufferImpl extends ByteBuffer
{
  private final boolean readOnly;

  ByteBufferImpl (byte[] buffer, int offset, int capacity, int limit,
		  int position, int mark, boolean readOnly)
  {
    super (capacity, limit, position, mark, null, buffer, offset);
    this.readOnly = readOnly;
  }
  
  public CharBuffer asCharBuffer ()
  {
    return new CharViewBufferImpl (this, remaining() >> 1);
  }

  public ShortBuffer asShortBuffer ()
  {
    return new ShortViewBufferImpl (this, remaining() >> 1);
  }

  public IntBuffer asIntBuffer ()
  {
    return new IntViewBufferImpl (this, remaining() >> 2);
  }

  public LongBuffer asLongBuffer ()
  {
    return new LongViewBufferImpl (this, remaining() >> 3);
  }

  public FloatBuffer asFloatBuffer ()
  {
    return new FloatViewBufferImpl (this, remaining() >> 2);
  }

  public DoubleBuffer asDoubleBuffer ()
  {
    return new DoubleViewBufferImpl (this, remaining() >> 3);
  }

  public boolean isReadOnly ()
  {
    return readOnly;
  }
  
  public ByteBuffer slice ()
  {
    return new ByteBufferImpl (backing_buffer, array_offset + position (),
			       remaining (), remaining (), 0, -1, isReadOnly ());
  }
  
  public ByteBuffer duplicate ()
  {
    return new ByteBufferImpl (backing_buffer, array_offset, capacity (),
			       limit (), position (), mark, isReadOnly ());
  }
  
  public ByteBuffer asReadOnlyBuffer ()
  {
    return new ByteBufferImpl (backing_buffer, array_offset, capacity (),
			       limit (), position (), mark, true);
  }
  
  void shiftDown (int dst_offset, int src_offset, int count)
  {
    System.arraycopy(backing_buffer, array_offset + src_offset,
		     backing_buffer, array_offset + dst_offset,
		     count);
  }

  public ByteBuffer compact ()
  {
    checkIfReadOnly();
    mark = -1;
    int pos = position();
    int n = limit() - pos;
    if (n > 0)
      shiftDown(0, pos, n);
    position(n);
    limit(capacity());
    return this;
  }
  
  public boolean isDirect ()
  {
    return false;
  }

  /**
   * Reads the <code>byte</code> at this buffer's current position,
   * and then increments the position.
   *
   * @exception BufferUnderflowException If there are no remaining
   * <code>bytes</code> in this buffer.
   */
  public byte get ()
  {
    if (pos >= limit)
        throw new BufferUnderflowException();

    return backing_buffer [(pos++) + array_offset];
  }

  /**
   * Bulk get
   */
  public ByteBuffer get (byte[] dst, int offset, int length)
  {
    checkArraySize(dst.length, offset, length);
    if ( (limit - pos) < length) // check for overflow
      throw new BufferUnderflowException();

    System.arraycopy(backing_buffer, pos + array_offset, 
		     dst, offset, length);
    pos += length;

    return this;
  }

  /**
   * Relative bulk put(), overloads the ByteBuffer impl.
   */
  public ByteBuffer put (byte[] src, int offset, int length)
  {
    if ( (limit - pos) < length) // check for overflow
      throw new BufferOverflowException();
    checkArraySize(src.length, offset, length);

    System.arraycopy(src, offset, backing_buffer, pos + array_offset, length);
    pos += length;

    return this;
  }

  /**
   * Relative put method. Writes <code>value</code> to the next position
   * in the buffer.
   *
   * @exception BufferOverflowException If there is no remaining
   * space in this buffer.
   * @exception ReadOnlyBufferException If this buffer is read-only.
   */
  public ByteBuffer put (byte value)
  {
    if (readOnly)
        throw new ReadOnlyBufferException();
    if (pos >= limit)
        throw new BufferOverflowException();

    backing_buffer [(pos++) + array_offset] = value;
    return this;
  }
  
  /**
   * Absolute get method. Reads the <code>byte</code> at position
   * <code>index</code>.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit.
   */
  public byte get (int index)
  {
    checkIndex(index);

    return backing_buffer [index + array_offset];
  }
  
  /**
   * Absolute put method. Writes <code>value</code> to position
   * <code>index</code> in the buffer.
   *
   * @exception IndexOutOfBoundsException If index is negative or not smaller
   * than the buffer's limit.
   * @exception ReadOnlyBufferException If this buffer is read-only.
   */
  public ByteBuffer put (int index, byte value)
  {
    checkIfReadOnly();
    checkIndex(index);

    backing_buffer [index + array_offset] = value;
    return this;
  }
  
  public char getChar ()
  {
    return ByteBufferHelper.getChar(this, order());
  }
  
  public ByteBuffer putChar (char value)
  {
    if (readOnly)
      throw new ReadOnlyBufferException ();
    if ( (limit-pos) < 2)
      throw new BufferOverflowException();

    if (endian == ByteOrder.LITTLE_ENDIAN)
      {
        backing_buffer [(pos++) + array_offset] = (byte)(value&0xFF);
        backing_buffer [(pos++) + array_offset] = (byte)(value>>8);
      }
    else
      {
        backing_buffer [(pos++) + array_offset] = (byte)(value>>8);
        backing_buffer [(pos++) + array_offset] = (byte)(value&0xFF);
      }
    return this;
  }
  
  public char getChar (int index)
  {
    return ByteBufferHelper.getChar(this, index, order());
  }
  
  public ByteBuffer putChar (int index, char value)
  {
    ByteBufferHelper.putChar(this, index, value, order());
    return this;
  }

  public short getShort ()
  {
    return ByteBufferHelper.getShort(this, order());
  }
  
  public ByteBuffer putShort (short value)
  {
    ByteBufferHelper.putShort(this, value, order());
    return this;
  }
  
  public short getShort (int index)
  {
    return ByteBufferHelper.getShort(this, index, order());
  }
  
  public ByteBuffer putShort (int index, short value)
  {
    ByteBufferHelper.putShort(this, index, value, order());
    return this;
  }

  public int getInt ()
  {
    return ByteBufferHelper.getInt(this, order());
  }
  
  public ByteBuffer putInt (int value)
  {
    ByteBufferHelper.putInt(this, value, order());
    return this;
  }
  
  public int getInt (int index)
  {
    return ByteBufferHelper.getInt(this, index, order());
  }
  
  public ByteBuffer putInt (int index, int value)
  {
    ByteBufferHelper.putInt(this, index, value, order());
    return this;
  }

  public long getLong ()
  {
    return ByteBufferHelper.getLong(this, order());
  }
  
  public ByteBuffer putLong (long value)
  {
    ByteBufferHelper.putLong (this, value, order());
    return this;
  }
  
  public long getLong (int index)
  {
    return ByteBufferHelper.getLong (this, index, order());
  }
  
  public ByteBuffer putLong (int index, long value)
  {
    ByteBufferHelper.putLong (this, index, value, order());
    return this;
  }

  public float getFloat ()
  {
    return ByteBufferHelper.getFloat (this, order());
  }
  
  public ByteBuffer putFloat (float value)
  {
    ByteBufferHelper.putFloat (this, value, order());
    return this;
  }
  
  public float getFloat (int index)
  {
    return ByteBufferHelper.getFloat (this, index, order());
  }

  public ByteBuffer putFloat (int index, float value)
  {
    ByteBufferHelper.putFloat (this, index, value, order());
    return this;
  }

  public double getDouble ()
  {
    return ByteBufferHelper.getDouble (this, order());
  }

  public ByteBuffer putDouble (double value)
  {
    ByteBufferHelper.putDouble (this, value, order());
    return this;
  }
  
  public double getDouble (int index)
  {
    return ByteBufferHelper.getDouble (this, index, order());
  }
  
  public ByteBuffer putDouble (int index, double value)
  {
    ByteBufferHelper.putDouble (this, index, value, order());
    return this;
  }
}
