/*
 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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;


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 array base offset
    private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);

    // 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 long size;
        private int capacity;

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

        public void run() {
            if (address == 0) {
                // Paranoia
                return;
            }
            unsafe.freeMemory(address);
            address = 0;
            Bits.unreserveMemory(size, 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);
        int ps = Bits.pageSize();
        int size = cap + ps;
        Bits.reserveMemory(size, cap);

        long base = 0;
        try {
            base = unsafe.allocateMemory(size);
        } catch (OutOfMemoryError x) {
            Bits.unreserveMemory(size, cap);
            throw x;
        }
        unsafe.setMemory(base, size, (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, size, 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[!byte]
            if (order() != ByteOrder.nativeOrder())
                Bits.copyTo$Memtype$Array(ix(pos), dst,
                                          offset << $LG_BYTES_PER_VALUE$,
                                          length << $LG_BYTES_PER_VALUE$);
            else
#end[!byte]
                Bits.copyToArray(ix(pos), dst, arrayBaseOffset,
                                 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[!byte]
            if (order() != ByteOrder.nativeOrder())
                Bits.copyFrom$Memtype$Array(src, offset << $LG_BYTES_PER_VALUE$,
                                            ix(pos), length << $LG_BYTES_PER_VALUE$);
            else
#end[!byte]
                Bits.copyFromArray(src, arrayBaseOffset, 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());
        discardMark();
        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 CharBuffer 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();
        return new DirectCharBuffer$RW$$BO$(this,
                                            -1,
                                            pos + start,
                                            pos + end,
                                            capacity(),
                                            offset);
    }

#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]

}
