/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package java.nio;

import org.apache.harmony.luni.platform.PlatformAddress;
import org.apache.harmony.luni.platform.PlatformAddressFactory;
import org.apache.harmony.nio.internal.DirectBuffer;

/**
 * DirectByteBuffer, ReadWriteDirectByteBuffer and ReadOnlyDirectByteBuffer
 * compose the implementation of platform memory based byte buffers.
 * <p>
 * DirectByteBuffer implements all the shared readonly methods and is extended
 * by the other two classes.
 * </p>
 * <p>
 * All methods are marked final for runtime performance.
 * </p>
 *
 */
abstract class DirectByteBuffer extends BaseByteBuffer implements DirectBuffer {

    // This class will help us track whether the address is valid or not.
    static final class SafeAddress {
        protected volatile boolean isValid = true;

        protected final PlatformAddress address;

        protected SafeAddress(PlatformAddress address) {
            super();
            this.address = address;
        }
    }

    // This is a wrapped reference to the base address of the buffer memory.
    protected final SafeAddress safeAddress;

    // This is the offset from the base address at which this buffer logically
    // starts.
    protected final int offset;

    /*
     * Constructs a new direct byte buffer of the given capacity on newly
     * allocated OS memory. The memory will have been zeroed. When the instance
     * is discarded the OS memory will be freed if it has not already been done
     * so by an explicit call to #free(). Callers are encouraged to explicitly
     * free the memory where possible.
     */
    DirectByteBuffer(int capacity) {
        this(new SafeAddress(PlatformAddressFactory.alloc(capacity, (byte) 0)),
                capacity, 0);
        safeAddress.address.autoFree();
    }

    DirectByteBuffer(SafeAddress address, int capacity, int offset) {
        super(capacity);

        // BEGIN android-added
        PlatformAddress baseAddress = address.address;
        long baseSize = baseAddress.getSize();

        if ((baseSize >= 0) && ((offset + capacity) > baseSize)) {
            throw new IllegalArgumentException("slice out of range");
        }
        // END android-added

        this.safeAddress = address;
        this.offset = offset;
    }

    /*
     * Override ByteBuffer.get(byte[], int, int) to improve performance.
     *
     * (non-Javadoc)
     *
     * @see java.nio.ByteBuffer#get(byte[], int, int)
     */
    @Override
    public final ByteBuffer get(byte[] dst, int off, int len) {
        int length = dst.length;
        if ((off < 0) || (len < 0) || (long) off + (long) len > length) {
            throw new IndexOutOfBoundsException();
        }
        if (len > remaining()) {
            throw new BufferUnderflowException();
        }
        getBaseAddress().getByteArray(offset + position, dst, off, len);
        position += len;
        return this;
    }

    @Override
    public final byte get() {
        if (position == limit) {
            throw new BufferUnderflowException();
        }
        return getBaseAddress().getByte(offset + position++);
    }

    @Override
    public final byte get(int index) {
        if (index < 0 || index >= limit) {
            throw new IndexOutOfBoundsException();
        }
        return getBaseAddress().getByte(offset + index);
    }

    @Override
    public final double getDouble() {
        int newPosition = position + 8;
        if (newPosition > limit) {
            throw new BufferUnderflowException();
        }
        double result = getBaseAddress().getDouble(offset + position, order);
        position = newPosition;
        return result;
    }

    @Override
    public final double getDouble(int index) {
        if (index < 0 || (long) index + 8 > limit) {
            throw new IndexOutOfBoundsException();
        }
        return getBaseAddress().getDouble(offset + index, order);
    }

    @Override
    public final float getFloat() {
        int newPosition = position + 4;
        if (newPosition > limit) {
            throw new BufferUnderflowException();
        }
        float result = getBaseAddress().getFloat(offset + position, order);
        position = newPosition;
        return result;
    }

    @Override
    public final float getFloat(int index) {
        if (index < 0 || (long) index + 4 > limit) {
            throw new IndexOutOfBoundsException();
        }
        return getBaseAddress().getFloat(offset + index, order);
    }

    @Override
    public final int getInt() {
        int newPosition = position + 4;
        if (newPosition > limit) {
            throw new BufferUnderflowException();
        }
        int result = getBaseAddress().getInt(offset + position, order);
        position = newPosition;
        return result;
    }

    @Override
    public final int getInt(int index) {
        if (index < 0 || (long) index + 4 > limit) {
            throw new IndexOutOfBoundsException();
        }
        return getBaseAddress().getInt(offset + index, order);
    }

    @Override
    public final long getLong() {
        int newPosition = position + 8;
        if (newPosition > limit) {
            throw new BufferUnderflowException();
        }
        long result = getBaseAddress().getLong(offset + position, order);
        position = newPosition;
        return result;
    }

    @Override
    public final long getLong(int index) {
        if (index < 0 || (long) index + 8 > limit) {
            throw new IndexOutOfBoundsException();
        }
        return getBaseAddress().getLong(offset + index, order);
    }

    @Override
    public final short getShort() {
        int newPosition = position + 2;
        if (newPosition > limit) {
            throw new BufferUnderflowException();
        }
        short result = getBaseAddress().getShort(offset + position, order);
        position = newPosition;
        return result;
    }

    @Override
    public final short getShort(int index) {
        if (index < 0 || (long) index + 2 > limit) {
            throw new IndexOutOfBoundsException();
        }
        return getBaseAddress().getShort(offset + index, order);
    }

    @Override
    public final boolean isDirect() {
        return true;
    }

    public final boolean isAddressValid() {
        return safeAddress.isValid;
    }

    public final void addressValidityCheck() {
        if (!isAddressValid()) {
            throw new IllegalStateException("Cannot use a direct byte buffer after it has been explicitly freed");
        }
    }

    private void markAddressInvalid() {
        safeAddress.isValid = false;
    }

    /*
     * Returns the base address of the buffer (i.e. before offset).
     */
    public final PlatformAddress getBaseAddress() {
        addressValidityCheck();
        return safeAddress.address;
    }

    /**
     * Returns the platform address of the start of this buffer instance.
     * <em>You must not attempt to free the returned address!!</em> It may not
     * be an address that was explicitly malloc'ed (i.e. if this buffer is the
     * result of a split); and it may be memory shared by multiple buffers.
     * <p>
     * If you can guarantee that you want to free the underlying memory call the
     * #free() method on this instance -- generally applications will rely on
     * the garbage collector to autofree this memory.
     * </p>
     *
     * @return the effective address of the start of the buffer.
     * @throws IllegalStateException
     *             if this buffer address is known to have been freed
     *             previously.
     */
    public final PlatformAddress getEffectiveAddress() {
        // BEGIN android-changed
        PlatformAddress addr = getBaseAddress().offsetBytes(offset);
        effectiveDirectAddress = addr.toInt();
        return addr;
        // END android-changed
    }

    /**
     * Explicitly free the memory used by this direct byte buffer. If the memory
     * has already been freed then this is a no-op. Once the memory has been
     * freed then operations requiring access to the memory will throw an
     * <code>IllegalStateException</code>.
     * <p>
     * Note this is is possible that the memory is freed by code that reaches
     * into the address and explicitly frees it 'beneith' us -- this is bad
     * form.
     * </p>
     */
    public final void free() {
        if (isAddressValid()) {
            markAddressInvalid();
            safeAddress.address.free();
        }
    }

    @Override
    final protected byte[] protectedArray() {
        throw new UnsupportedOperationException();
    }

    @Override
    final protected int protectedArrayOffset() {
        throw new UnsupportedOperationException();
    }

    @Override
    final protected boolean protectedHasArray() {
        return false;
    }

    public final int getByteCapacity() {
        return capacity;
    }
}
