| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * Copyright (c) 2000, 2011, 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. |
| */ |
| |
| package java.nio; |
| |
| import java.io.FileDescriptor; |
| |
| import dalvik.system.VMRuntime; |
| import libcore.io.Memory; |
| import libcore.io.SizeOf; |
| import sun.misc.Cleaner; |
| import sun.nio.ch.DirectBuffer; |
| |
| /** @hide */ |
| public class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer { |
| |
| /** |
| * Stores the details of the memory backing a DirectByteBuffer. This could be a pointer |
| * (passed through from JNI or resulting from a mapping) or a non-movable byte array allocated |
| * from Java. Each MemoryRef also has an isAccessible associated with it, which determines |
| * whether the underlying memory is "accessible". The notion of "accessibility" is usually |
| * defined by the allocator of the reference, and is separate from the accessibility of the |
| * memory as defined by the underlying system. |
| * |
| * A single MemoryRef instance is shared across all slices and duplicates of a given buffer. |
| */ |
| static class MemoryRef { |
| byte[] buffer; |
| long allocatedAddress; |
| final int offset; |
| boolean isAccessible; |
| |
| MemoryRef(int capacity) { |
| VMRuntime runtime = VMRuntime.getRuntime(); |
| buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7); |
| allocatedAddress = runtime.addressOf(buffer); |
| // Offset is set to handle the alignment: http://b/16449607 |
| offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress); |
| isAccessible = true; |
| } |
| |
| MemoryRef(long allocatedAddress) { |
| buffer = null; |
| this.allocatedAddress = allocatedAddress; |
| this.offset = 0; |
| isAccessible = true; |
| } |
| |
| void free() { |
| buffer = null; |
| allocatedAddress = 0; |
| isAccessible = false; |
| } |
| } |
| |
| final Cleaner cleaner; |
| final MemoryRef memoryRef; |
| |
| DirectByteBuffer(int capacity, MemoryRef memoryRef) { |
| super(-1, 0, capacity, capacity, memoryRef.buffer, memoryRef.offset); |
| // Only have references to java objects, no need for a cleaner since the GC will do all |
| // the work. |
| this.memoryRef = memoryRef; |
| this.address = memoryRef.allocatedAddress + memoryRef.offset; |
| cleaner = null; |
| this.isReadOnly = false; |
| } |
| |
| // Invoked only by JNI: NewDirectByteBuffer(void*, long) |
| // |
| private DirectByteBuffer(long addr, int cap) { |
| super(-1, 0, cap, cap); |
| memoryRef = new MemoryRef(addr); |
| address = addr; |
| cleaner = null; |
| } |
| |
| /** @hide */ |
| public DirectByteBuffer(int cap, long addr, |
| FileDescriptor fd, |
| Runnable unmapper, |
| boolean isReadOnly) { |
| super(-1, 0, cap, cap, fd); |
| this.isReadOnly = isReadOnly; |
| memoryRef = new MemoryRef(addr); |
| address = addr; |
| cleaner = Cleaner.create(memoryRef, unmapper); |
| } |
| |
| // For duplicates and slices |
| // |
| DirectByteBuffer(MemoryRef memoryRef, // package-private |
| int mark, int pos, int lim, int cap, |
| int off) { |
| this(memoryRef, mark, pos, lim, cap, off, false); |
| } |
| |
| DirectByteBuffer(MemoryRef memoryRef, // package-private |
| int mark, int pos, int lim, int cap, |
| int off, boolean isReadOnly) { |
| super(mark, pos, lim, cap, memoryRef.buffer, off); |
| this.isReadOnly = isReadOnly; |
| this.memoryRef = memoryRef; |
| address = memoryRef.allocatedAddress + off; |
| cleaner = null; |
| } |
| |
| @Override |
| public Object attachment() { |
| return memoryRef; |
| } |
| |
| @Override |
| public Cleaner cleaner() { |
| return cleaner; |
| } |
| |
| public ByteBuffer slice() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int pos = position(); |
| int lim = limit(); |
| assert (pos <= lim); |
| int rem = (pos <= lim ? lim - pos : 0); |
| int off = pos + offset; |
| assert (off >= 0); |
| return new DirectByteBuffer(memoryRef, -1, 0, rem, rem, off, isReadOnly); |
| } |
| |
| public ByteBuffer duplicate() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return new DirectByteBuffer(memoryRef, |
| this.markValue(), |
| this.position(), |
| this.limit(), |
| this.capacity(), |
| offset, |
| isReadOnly); |
| } |
| |
| public ByteBuffer asReadOnlyBuffer() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return new DirectByteBuffer(memoryRef, |
| this.markValue(), |
| this.position(), |
| this.limit(), |
| this.capacity(), |
| offset, |
| true); |
| } |
| |
| @Override |
| public long address() { |
| return address; |
| } |
| |
| private long ix(int i) { |
| return address + i; |
| } |
| |
| private byte get(long a) { |
| return Memory.peekByte(a); |
| } |
| |
| public byte get() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return get(ix(nextGetIndex())); |
| } |
| |
| public byte get(int i) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return get(ix(checkIndex(i))); |
| } |
| |
| public ByteBuffer get(byte[] dst, int dstOffset, int length) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| checkBounds(dstOffset, 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(); |
| Memory.peekByteArray(ix(pos), |
| dst, dstOffset, length); |
| position = pos + length; |
| return this; |
| } |
| |
| public ByteBuffer put(long a, byte x) { |
| Memory.pokeByte(a, x); |
| return this; |
| } |
| |
| public ByteBuffer put(byte x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| put(ix(nextPutIndex()), x); |
| return this; |
| } |
| |
| public ByteBuffer put(int i, byte x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| put(ix(checkIndex(i)), x); |
| return this; |
| } |
| |
| public ByteBuffer put(byte[] src, int srcOffset, int length) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| checkBounds(srcOffset, 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(); |
| Memory.pokeByteArray(ix(pos), |
| src, srcOffset, length); |
| position = pos + length; |
| return this; |
| } |
| |
| public ByteBuffer compact() { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int pos = position(); |
| int lim = limit(); |
| assert (pos <= lim); |
| int rem = (pos <= lim ? lim - pos : 0); |
| System.arraycopy(hb, position + offset, hb, offset, remaining()); |
| position(rem); |
| limit(capacity()); |
| discardMark(); |
| return this; |
| } |
| |
| public boolean isDirect() { |
| return true; |
| } |
| |
| public boolean isReadOnly() { |
| return isReadOnly; |
| } |
| |
| byte _get(int i) { // package-private |
| return get(i); |
| } |
| |
| void _put(int i, byte b) { // package-private |
| put(i, b); |
| } |
| |
| private char getChar(long a) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return (char) Memory.peekShort(position, !nativeByteOrder); |
| } |
| |
| public char getChar() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int newPosition = position + SizeOf.CHAR; |
| if (newPosition > limit()) { |
| throw new BufferUnderflowException(); |
| } |
| char x = (char) Memory.peekShort(ix(position), !nativeByteOrder); |
| position = newPosition; |
| return x; |
| } |
| |
| public char getChar(int i) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| checkIndex(i, SizeOf.CHAR); |
| char x = (char) Memory.peekShort(ix(i), !nativeByteOrder); |
| return x; |
| } |
| |
| char getCharUnchecked(int i) { |
| return (char) Memory.peekShort(ix(i), !nativeByteOrder); |
| } |
| |
| void getUnchecked(int pos, char[] dst, int dstOffset, int length) { |
| Memory.peekCharArray(ix(pos), |
| dst, dstOffset, length, !nativeByteOrder); |
| } |
| |
| |
| private ByteBuffer putChar(long a, char x) { |
| Memory.pokeShort(a, (short) x, !nativeByteOrder); |
| return this; |
| } |
| |
| public ByteBuffer putChar(char x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putChar(ix(nextPutIndex(SizeOf.CHAR)), x); |
| return this; |
| } |
| |
| public ByteBuffer putChar(int i, char x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putChar(ix(checkIndex(i, SizeOf.CHAR)), x); |
| return this; |
| } |
| |
| void putCharUnchecked(int i, char x) { |
| putChar(ix(i), x); |
| } |
| |
| void putUnchecked(int pos, char[] src, int srcOffset, int length) { |
| Memory.pokeCharArray(ix(pos), |
| src, srcOffset, length, !nativeByteOrder); |
| } |
| |
| public CharBuffer asCharBuffer() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int off = this.position(); |
| int lim = this.limit(); |
| assert (off <= lim); |
| int rem = (off <= lim ? lim - off : 0); |
| int size = rem >> 1; |
| return (CharBuffer) (new ByteBufferAsCharBuffer(this, |
| -1, |
| 0, |
| size, |
| size, |
| off, |
| order())); |
| } |
| |
| private short getShort(long a) { |
| return Memory.peekShort(a, !nativeByteOrder); |
| } |
| |
| public short getShort() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getShort(ix(nextGetIndex(SizeOf.SHORT))); |
| } |
| |
| public short getShort(int i) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getShort(ix(checkIndex(i, SizeOf.SHORT))); |
| } |
| |
| short getShortUnchecked(int i) { |
| return getShort(ix(i)); |
| } |
| |
| void getUnchecked(int pos, short[] dst, int dstOffset, int length) { |
| Memory.peekShortArray(ix(pos), |
| dst, dstOffset, length, !nativeByteOrder); |
| } |
| |
| |
| private ByteBuffer putShort(long a, short x) { |
| Memory.pokeShort(a, x, !nativeByteOrder); |
| return this; |
| } |
| |
| public ByteBuffer putShort(short x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putShort(ix(nextPutIndex(SizeOf.SHORT)), x); |
| return this; |
| } |
| |
| public ByteBuffer putShort(int i, short x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putShort(ix(checkIndex(i, SizeOf.SHORT)), x); |
| return this; |
| } |
| |
| void putShortUnchecked(int i, short x) { |
| putShort(ix(i), x); |
| } |
| |
| void putUnchecked(int pos, short[] src, int srcOffset, int length) { |
| Memory.pokeShortArray(ix(pos), |
| src, srcOffset, length, !nativeByteOrder); |
| } |
| |
| public ShortBuffer asShortBuffer() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int off = this.position(); |
| int lim = this.limit(); |
| assert (off <= lim); |
| int rem = (off <= lim ? lim - off : 0); |
| int size = rem >> 1; |
| return (ShortBuffer) (new ByteBufferAsShortBuffer(this, |
| -1, |
| 0, |
| size, |
| size, |
| off, |
| order())); |
| } |
| |
| private int getInt(long a) { |
| return Memory.peekInt(a, !nativeByteOrder); |
| } |
| |
| public int getInt() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getInt(ix(nextGetIndex(SizeOf.INT))); |
| } |
| |
| public int getInt(int i) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getInt(ix(checkIndex(i, (SizeOf.INT)))); |
| } |
| |
| int getIntUnchecked(int i) { |
| return getInt(ix(i)); |
| } |
| |
| void getUnchecked(int pos, int[] dst, int dstOffset, int length) { |
| Memory.peekIntArray(ix(pos), |
| dst, dstOffset, length, !nativeByteOrder); |
| } |
| |
| private ByteBuffer putInt(long a, int x) { |
| Memory.pokeInt(a, x, !nativeByteOrder); |
| return this; |
| } |
| |
| public ByteBuffer putInt(int x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putInt(ix(nextPutIndex(SizeOf.INT)), x); |
| return this; |
| } |
| |
| public ByteBuffer putInt(int i, int x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putInt(ix(checkIndex(i, SizeOf.INT)), x); |
| return this; |
| } |
| |
| void putIntUnchecked(int i, int x) { |
| putInt(ix(i), x); |
| } |
| |
| void putUnchecked(int pos, int[] src, int srcOffset, int length) { |
| Memory.pokeIntArray(ix(pos), |
| src, srcOffset, length, !nativeByteOrder); |
| } |
| |
| |
| public IntBuffer asIntBuffer() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int off = this.position(); |
| int lim = this.limit(); |
| assert (off <= lim); |
| int rem = (off <= lim ? lim - off : 0); |
| int size = rem >> 2; |
| return (IntBuffer) (new ByteBufferAsIntBuffer(this, |
| -1, |
| 0, |
| size, |
| size, |
| off, |
| order())); |
| } |
| |
| private long getLong(long a) { |
| return Memory.peekLong(a, !nativeByteOrder); |
| } |
| |
| public long getLong() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getLong(ix(nextGetIndex(SizeOf.LONG))); |
| } |
| |
| public long getLong(int i) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getLong(ix(checkIndex(i, SizeOf.LONG))); |
| } |
| |
| long getLongUnchecked(int i) { |
| return getLong(ix(i)); |
| } |
| |
| void getUnchecked(int pos, long[] dst, int dstOffset, int length) { |
| Memory.peekLongArray(ix(pos), |
| dst, dstOffset, length, !nativeByteOrder); |
| } |
| |
| private ByteBuffer putLong(long a, long x) { |
| Memory.pokeLong(a, x, !nativeByteOrder); |
| return this; |
| } |
| |
| public ByteBuffer putLong(long x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putLong(ix(nextPutIndex(SizeOf.LONG)), x); |
| return this; |
| } |
| |
| public ByteBuffer putLong(int i, long x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putLong(ix(checkIndex(i, SizeOf.LONG)), x); |
| return this; |
| } |
| |
| void putLongUnchecked(int i, long x) { |
| putLong(ix(i), x); |
| } |
| |
| void putUnchecked(int pos, long[] src, int srcOffset, int length) { |
| Memory.pokeLongArray(ix(pos), |
| src, srcOffset, length, !nativeByteOrder); |
| } |
| |
| |
| public LongBuffer asLongBuffer() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int off = this.position(); |
| int lim = this.limit(); |
| assert (off <= lim); |
| int rem = (off <= lim ? lim - off : 0); |
| int size = rem >> 3; |
| return (LongBuffer) (new ByteBufferAsLongBuffer(this, |
| -1, |
| 0, |
| size, |
| size, |
| off, |
| order())); |
| } |
| |
| private float getFloat(long a) { |
| int x = Memory.peekInt(a, !nativeByteOrder); |
| return Float.intBitsToFloat(x); |
| } |
| |
| public float getFloat() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getFloat(ix(nextGetIndex(SizeOf.FLOAT))); |
| } |
| |
| public float getFloat(int i) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getFloat(ix(checkIndex(i, SizeOf.FLOAT))); |
| } |
| |
| float getFloatUnchecked(int i) { |
| return getFloat(ix(i)); |
| } |
| |
| void getUnchecked(int pos, float[] dst, int dstOffset, int length) { |
| Memory.peekFloatArray(ix(pos), |
| dst, dstOffset, length, !nativeByteOrder); |
| } |
| |
| private ByteBuffer putFloat(long a, float x) { |
| int y = Float.floatToRawIntBits(x); |
| Memory.pokeInt(a, y, !nativeByteOrder); |
| return this; |
| } |
| |
| public ByteBuffer putFloat(float x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putFloat(ix(nextPutIndex(SizeOf.FLOAT)), x); |
| return this; |
| } |
| |
| public ByteBuffer putFloat(int i, float x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putFloat(ix(checkIndex(i, SizeOf.FLOAT)), x); |
| return this; |
| } |
| |
| void putFloatUnchecked(int i, float x) { |
| putFloat(ix(i), x); |
| } |
| |
| void putUnchecked(int pos, float[] src, int srcOffset, int length) { |
| Memory.pokeFloatArray(ix(pos), |
| src, srcOffset, length, !nativeByteOrder); |
| } |
| |
| public FloatBuffer asFloatBuffer() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int off = this.position(); |
| int lim = this.limit(); |
| assert (off <= lim); |
| int rem = (off <= lim ? lim - off : 0); |
| int size = rem >> 2; |
| return (FloatBuffer) (new ByteBufferAsFloatBuffer(this, |
| -1, |
| 0, |
| size, |
| size, |
| off, |
| order())); |
| } |
| |
| private double getDouble(long a) { |
| long x = Memory.peekLong(a, !nativeByteOrder); |
| return Double.longBitsToDouble(x); |
| } |
| |
| public double getDouble() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getDouble(ix(nextGetIndex(SizeOf.DOUBLE))); |
| } |
| |
| public double getDouble(int i) { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| return getDouble(ix(checkIndex(i, SizeOf.DOUBLE))); |
| } |
| |
| double getDoubleUnchecked(int i) { |
| return getDouble(ix(i)); |
| } |
| |
| void getUnchecked(int pos, double[] dst, int dstOffset, int length) { |
| Memory.peekDoubleArray(ix(pos), |
| dst, dstOffset, length, !nativeByteOrder); |
| } |
| |
| private ByteBuffer putDouble(long a, double x) { |
| long y = Double.doubleToRawLongBits(x); |
| Memory.pokeLong(a, y, !nativeByteOrder); |
| return this; |
| } |
| |
| public ByteBuffer putDouble(double x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putDouble(ix(nextPutIndex(SizeOf.DOUBLE)), x); |
| return this; |
| } |
| |
| public ByteBuffer putDouble(int i, double x) { |
| if (isReadOnly) { |
| throw new ReadOnlyBufferException(); |
| } |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| putDouble(ix(checkIndex(i, SizeOf.DOUBLE)), x); |
| return this; |
| } |
| |
| void putDoubleUnchecked(int i, double x) { |
| putDouble(ix(i), x); |
| } |
| |
| void putUnchecked(int pos, double[] src, int srcOffset, int length) { |
| Memory.pokeDoubleArray(ix(pos), |
| src, srcOffset, length, !nativeByteOrder); |
| } |
| |
| public DoubleBuffer asDoubleBuffer() { |
| if (!memoryRef.isAccessible) { |
| throw new IllegalStateException("buffer is inaccessible"); |
| } |
| int off = this.position(); |
| int lim = this.limit(); |
| assert (off <= lim); |
| int rem = (off <= lim ? lim - off : 0); |
| |
| int size = rem >> 3; |
| return (DoubleBuffer) (new ByteBufferAsDoubleBuffer(this, |
| -1, |
| 0, |
| size, |
| size, |
| off, |
| order())); |
| } |
| |
| public boolean isAccessible() { |
| return memoryRef.isAccessible; |
| } |
| |
| public void setAccessible(boolean value) { |
| memoryRef.isAccessible = value; |
| } |
| } |