/*
 * Copyright 2000-2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#warn This file is preprocessed before being compiled

package java.nio;

import sun.misc.Cleaner;
import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;
import sun.nio.ch.FileChannelImpl;


class Direct$Type$Buffer$RW$$BO$
#if[rw]
    extends {#if[byte]?Mapped$Type$Buffer:$Type$Buffer}
#else[rw]
    extends Direct$Type$Buffer$BO$
#end[rw]
    implements DirectBuffer
{

#if[rw]

    // Cached unsafe-access object
    protected static final Unsafe unsafe = Bits.unsafe();

    // Cached unaligned-access capability
    protected static final boolean unaligned = Bits.unaligned();

    // Base address, used in all indexing calculations
    // NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
    //    protected long address;

    // If this buffer is a view of another buffer then we keep a reference to
    // that buffer so that its memory isn't freed before we're done with it
    protected Object viewedBuffer = null;

    public Object viewedBuffer() {
        return viewedBuffer;
    }

#if[byte]

    private static class Deallocator
        implements Runnable
    {

        private static Unsafe unsafe = Unsafe.getUnsafe();

        private long address;
        private int capacity;

        private Deallocator(long address, int capacity) {
            assert (address != 0);
            this.address = address;
            this.capacity = capacity;
        }

        public void run() {
            if (address == 0) {
                // Paranoia
                return;
            }
            unsafe.freeMemory(address);
            address = 0;
            Bits.unreserveMemory(capacity);
        }

    }

    private final Cleaner cleaner;

    public Cleaner cleaner() { return cleaner; }

#else[byte]

    public Cleaner cleaner() { return null; }

#end[byte]

#end[rw]

#if[byte]

    // Primary constructor
    //
    Direct$Type$Buffer$RW$(int cap) {                   // package-private
#if[rw]
        super(-1, 0, cap, cap, false);
        Bits.reserveMemory(cap);
        int ps = Bits.pageSize();
        long base = 0;
        try {
            base = unsafe.allocateMemory(cap + ps);
        } catch (OutOfMemoryError x) {
            Bits.unreserveMemory(cap);
            throw x;
        }
        unsafe.setMemory(base, cap + ps, (byte) 0);
        if (base % ps != 0) {
            // Round up to page boundary
            address = base + ps - (base & (ps - 1));
        } else {
            address = base;
        }
        cleaner = Cleaner.create(this, new Deallocator(base, cap));
#else[rw]
        super(cap);
#end[rw]
    }

#if[rw]

    // Invoked only by JNI: NewDirectByteBuffer(void*, long)
    //
    private Direct$Type$Buffer(long addr, int cap) {
        super(-1, 0, cap, cap, false);
        address = addr;
        cleaner = null;
    }

#end[rw]

    // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
    //
    protected Direct$Type$Buffer$RW$(int cap, long addr, Runnable unmapper) {
#if[rw]
        super(-1, 0, cap, cap, true);
        address = addr;
        viewedBuffer = null;
        cleaner = Cleaner.create(this, unmapper);
#else[rw]
        super(cap, addr, unmapper);
#end[rw]
    }

#end[byte]

    // For duplicates and slices
    //
    Direct$Type$Buffer$RW$$BO$(DirectBuffer db,         // package-private
                               int mark, int pos, int lim, int cap,
                               int off)
    {
#if[rw]
        super(mark, pos, lim, cap);
        address = db.address() + off;
        viewedBuffer = db;
#if[byte]
        cleaner = null;
#end[byte]
#else[rw]
        super(db, mark, pos, lim, cap, off);
#end[rw]
    }

    public $Type$Buffer slice() {
        int pos = this.position();
        int lim = this.limit();
        assert (pos <= lim);
        int rem = (pos <= lim ? lim - pos : 0);
        int off = (pos << $LG_BYTES_PER_VALUE$);
        assert (off >= 0);
        return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off);
    }

    public $Type$Buffer duplicate() {
        return new Direct$Type$Buffer$RW$$BO$(this,
                                              this.markValue(),
                                              this.position(),
                                              this.limit(),
                                              this.capacity(),
                                              0);
    }

    public $Type$Buffer asReadOnlyBuffer() {
#if[rw]
        return new Direct$Type$BufferR$BO$(this,
                                           this.markValue(),
                                           this.position(),
                                           this.limit(),
                                           this.capacity(),
                                           0);
#else[rw]
        return duplicate();
#end[rw]
    }

#if[rw]

    public long address() {
        return address;
    }

    private long ix(int i) {
        return address + (i << $LG_BYTES_PER_VALUE$);
    }

    public $type$ get() {
        return $fromBits$($swap$(unsafe.get$Swaptype$(ix(nextGetIndex()))));
    }

    public $type$ get(int i) {
        return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
    }

    public $Type$Buffer get($type$[] dst, int offset, int length) {
#if[rw]
        if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
            checkBounds(offset, length, dst.length);
            int pos = position();
            int lim = limit();
            assert (pos <= lim);
            int rem = (pos <= lim ? lim - pos : 0);
            if (length > rem)
                throw new BufferUnderflowException();

            if (order() != ByteOrder.nativeOrder())
                Bits.copyTo$Memtype$Array(ix(pos), dst,
                                          offset << $LG_BYTES_PER_VALUE$,
                                          length << $LG_BYTES_PER_VALUE$);
            else
                Bits.copyToByteArray(ix(pos), dst,
                                     offset << $LG_BYTES_PER_VALUE$,
                                     length << $LG_BYTES_PER_VALUE$);
            position(pos + length);
        } else {
            super.get(dst, offset, length);
        }
        return this;
#else[rw]
        throw new ReadOnlyBufferException();
#end[rw]
    }

#end[rw]

    public $Type$Buffer put($type$ x) {
#if[rw]
        unsafe.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
        return this;
#else[rw]
        throw new ReadOnlyBufferException();
#end[rw]
    }

    public $Type$Buffer put(int i, $type$ x) {
#if[rw]
        unsafe.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
        return this;
#else[rw]
        throw new ReadOnlyBufferException();
#end[rw]
    }

    public $Type$Buffer put($Type$Buffer src) {
#if[rw]
        if (src instanceof Direct$Type$Buffer$BO$) {
            if (src == this)
                throw new IllegalArgumentException();
            Direct$Type$Buffer$RW$$BO$ sb = (Direct$Type$Buffer$RW$$BO$)src;

            int spos = sb.position();
            int slim = sb.limit();
            assert (spos <= slim);
            int srem = (spos <= slim ? slim - spos : 0);

            int pos = position();
            int lim = limit();
            assert (pos <= lim);
            int rem = (pos <= lim ? lim - pos : 0);

            if (srem > rem)
                throw new BufferOverflowException();
            unsafe.copyMemory(sb.ix(spos), ix(pos), srem << $LG_BYTES_PER_VALUE$);
            sb.position(spos + srem);
            position(pos + srem);
        } else if (src.hb != null) {

            int spos = src.position();
            int slim = src.limit();
            assert (spos <= slim);
            int srem = (spos <= slim ? slim - spos : 0);

            put(src.hb, src.offset + spos, srem);
            src.position(spos + srem);

        } else {
            super.put(src);
        }
        return this;
#else[rw]
        throw new ReadOnlyBufferException();
#end[rw]
    }

    public $Type$Buffer put($type$[] src, int offset, int length) {
#if[rw]
        if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
            checkBounds(offset, length, src.length);
            int pos = position();
            int lim = limit();
            assert (pos <= lim);
            int rem = (pos <= lim ? lim - pos : 0);
            if (length > rem)
                throw new BufferOverflowException();

            if (order() != ByteOrder.nativeOrder())
                Bits.copyFrom$Memtype$Array(src, offset << $LG_BYTES_PER_VALUE$,
                                            ix(pos), length << $LG_BYTES_PER_VALUE$);
            else
                Bits.copyFromByteArray(src, offset << $LG_BYTES_PER_VALUE$,
                                       ix(pos), length << $LG_BYTES_PER_VALUE$);
            position(pos + length);
        } else {
            super.put(src, offset, length);
        }
        return this;
#else[rw]
        throw new ReadOnlyBufferException();
#end[rw]
    }

    public $Type$Buffer compact() {
#if[rw]
        int pos = position();
        int lim = limit();
        assert (pos <= lim);
        int rem = (pos <= lim ? lim - pos : 0);

        unsafe.copyMemory(ix(pos), ix(0), rem << $LG_BYTES_PER_VALUE$);
        position(rem);
        limit(capacity());
        return this;
#else[rw]
        throw new ReadOnlyBufferException();
#end[rw]
    }

    public boolean isDirect() {
        return true;
    }

    public boolean isReadOnly() {
        return {#if[rw]?false:true};
    }


#if[char]

    public String toString(int start, int end) {
        if ((end > limit()) || (start > end))
            throw new IndexOutOfBoundsException();
        try {
            int len = end - start;
            char[] ca = new char[len];
            CharBuffer cb = CharBuffer.wrap(ca);
            CharBuffer db = this.duplicate();
            db.position(start);
            db.limit(end);
            cb.put(db);
            return new String(ca);
        } catch (StringIndexOutOfBoundsException x) {
            throw new IndexOutOfBoundsException();
        }
    }


    // --- Methods to support CharSequence ---

    public CharSequence subSequence(int start, int end) {
        int pos = position();
        int lim = limit();
        assert (pos <= lim);
        pos = (pos <= lim ? pos : lim);
        int len = lim - pos;

        if ((start < 0) || (end > len) || (start > end))
            throw new IndexOutOfBoundsException();
        int sublen = end - start;
        int off = (pos + start) << $LG_BYTES_PER_VALUE$;
        assert (off >= 0);
        return new DirectCharBuffer$RW$$BO$(this, -1, 0, sublen, sublen, off);
    }

#end[char]



#if[!byte]

    public ByteOrder order() {
#if[boS]
        return ((ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
#end[boS]
#if[boU]
        return ((ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN)
                ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
#end[boU]
    }

#end[!byte]



#if[byte]

    byte _get(int i) {                          // package-private
        return unsafe.getByte(address + i);
    }

    void _put(int i, byte b) {                  // package-private
#if[rw]
        unsafe.putByte(address + i, b);
#else[rw]
        throw new ReadOnlyBufferException();
#end[rw]
    }

    // #BIN
    //
    // Binary-data access methods  for short, char, int, long, float,
    // and double will be inserted here

#end[byte]

}
