/*
 * Copyright (c) 2000, 2015, 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 java.io.FileDescriptor;
import sun.misc.Cleaner;
import jdk.internal.misc.Unsafe;
import sun.misc.VM;
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;

    // An object attached to this buffer. If this buffer is a view of another
    // buffer then we use this field to keep a reference to that buffer to
    // ensure that its memory isn't freed before we are done with it.
    private final Object att;

    public Object attachment() {
        return att;
    }

#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);
        boolean pa = VM.isDirectMemoryPageAligned();
        int ps = Bits.pageSize();
        long size = Math.max(1L, (long)cap + (pa ? ps : 0));
        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 (pa && (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));
        att = null;
#else[rw]
        super(cap);
#end[rw]
    }

#if[rw]

    // Invoked to construct a direct ByteBuffer referring to the block of
    // memory. A given arbitrary object may also be attached to the buffer.
    //
    Direct$Type$Buffer(long addr, int cap, Object ob) {
        super(-1, 0, cap, cap);
        address = addr;
        cleaner = null;
        att = ob;
    }


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

#end[rw]

    // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
    //
    protected Direct$Type$Buffer$RW$(int cap, long addr,
                                     FileDescriptor fd,
                                     Runnable unmapper)
    {
#if[rw]
        super(-1, 0, cap, cap, fd);
        address = addr;
        cleaner = Cleaner.create(this, unmapper);
        att = null;
#else[rw]
        super(cap, addr, fd, 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;
#if[byte]
        cleaner = null;
#end[byte]
        att = db;
#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 + ((long)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)))));
    }

#if[streamableType]
    $type$ getUnchecked(int i) {
        return $fromBits$($swap$(unsafe.get$Swaptype$(ix(i))));
    }
#end[streamableType]

    public $Type$Buffer get($type$[] dst, int offset, int length) {
#if[rw]
        if (((long)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,
                                          (long)offset << $LG_BYTES_PER_VALUE$,
                                          (long)length << $LG_BYTES_PER_VALUE$);
            else
#end[!byte]
                Bits.copyToArray(ix(pos), dst, arrayBaseOffset,
                                 (long)offset << $LG_BYTES_PER_VALUE$,
                                 (long)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 createSameBufferException();
            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), (long)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 (((long)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,
                                            (long)offset << $LG_BYTES_PER_VALUE$,
                                            ix(pos),
                                            (long)length << $LG_BYTES_PER_VALUE$);
            else
#end[!byte]
                Bits.copyFromArray(src, arrayBaseOffset,
                                   (long)offset << $LG_BYTES_PER_VALUE$,
                                   ix(pos),
                                   (long)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), (long)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]

}
