0N/A/*
4352N/A * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/A#warn This file is preprocessed before being compiled
0N/A
0N/Apackage java.nio;
0N/A
2984N/Aimport java.io.FileDescriptor;
0N/Aimport sun.misc.Cleaner;
0N/Aimport sun.misc.Unsafe;
2936N/Aimport sun.misc.VM;
0N/Aimport sun.nio.ch.DirectBuffer;
0N/A
0N/A
0N/Aclass Direct$Type$Buffer$RW$$BO$
0N/A#if[rw]
0N/A extends {#if[byte]?Mapped$Type$Buffer:$Type$Buffer}
0N/A#else[rw]
0N/A extends Direct$Type$Buffer$BO$
0N/A#end[rw]
0N/A implements DirectBuffer
0N/A{
0N/A
0N/A#if[rw]
0N/A
0N/A // Cached unsafe-access object
0N/A protected static final Unsafe unsafe = Bits.unsafe();
0N/A
523N/A // Cached array base offset
523N/A private static final long arrayBaseOffset = (long)unsafe.arrayBaseOffset($type$[].class);
523N/A
0N/A // Cached unaligned-access capability
0N/A protected static final boolean unaligned = Bits.unaligned();
0N/A
0N/A // Base address, used in all indexing calculations
0N/A // NOTE: moved up to Buffer.java for speed in JNI GetDirectBufferAddress
0N/A // protected long address;
0N/A
4352N/A // An object attached to this buffer. If this buffer is a view of another
4352N/A // buffer then we use this field to keep a reference to that buffer to
4352N/A // ensure that its memory isn't freed before we are done with it.
4352N/A private final Object att;
0N/A
4352N/A public Object attachment() {
4352N/A return att;
0N/A }
0N/A
0N/A#if[byte]
0N/A
0N/A private static class Deallocator
0N/A implements Runnable
0N/A {
0N/A
0N/A private static Unsafe unsafe = Unsafe.getUnsafe();
0N/A
0N/A private long address;
515N/A private long size;
0N/A private int capacity;
0N/A
515N/A private Deallocator(long address, long size, int capacity) {
0N/A assert (address != 0);
0N/A this.address = address;
515N/A this.size = size;
0N/A this.capacity = capacity;
0N/A }
0N/A
0N/A public void run() {
0N/A if (address == 0) {
0N/A // Paranoia
0N/A return;
0N/A }
0N/A unsafe.freeMemory(address);
0N/A address = 0;
515N/A Bits.unreserveMemory(size, capacity);
0N/A }
0N/A
0N/A }
0N/A
0N/A private final Cleaner cleaner;
0N/A
0N/A public Cleaner cleaner() { return cleaner; }
0N/A
0N/A#else[byte]
0N/A
0N/A public Cleaner cleaner() { return null; }
0N/A
0N/A#end[byte]
0N/A
0N/A#end[rw]
0N/A
0N/A#if[byte]
0N/A
0N/A // Primary constructor
0N/A //
0N/A Direct$Type$Buffer$RW$(int cap) { // package-private
0N/A#if[rw]
2984N/A super(-1, 0, cap, cap);
2936N/A boolean pa = VM.isDirectMemoryPageAligned();
0N/A int ps = Bits.pageSize();
2936N/A long size = Math.max(1L, (long)cap + (pa ? ps : 0));
515N/A Bits.reserveMemory(size, cap);
515N/A
0N/A long base = 0;
0N/A try {
515N/A base = unsafe.allocateMemory(size);
0N/A } catch (OutOfMemoryError x) {
515N/A Bits.unreserveMemory(size, cap);
0N/A throw x;
0N/A }
515N/A unsafe.setMemory(base, size, (byte) 0);
2936N/A if (pa && (base % ps != 0)) {
0N/A // Round up to page boundary
0N/A address = base + ps - (base & (ps - 1));
0N/A } else {
0N/A address = base;
0N/A }
515N/A cleaner = Cleaner.create(this, new Deallocator(base, size, cap));
4352N/A att = null;
0N/A#else[rw]
0N/A super(cap);
0N/A#end[rw]
0N/A }
0N/A
0N/A#if[rw]
0N/A
4352N/A // Invoked to construct a direct ByteBuffer referring to the block of
4352N/A // memory. A given arbitrary object may also be attached to the buffer.
4352N/A //
4352N/A Direct$Type$Buffer(long addr, int cap, Object ob) {
4352N/A super(-1, 0, cap, cap);
4352N/A address = addr;
4352N/A cleaner = null;
4352N/A att = ob;
4352N/A }
4352N/A
4352N/A
0N/A // Invoked only by JNI: NewDirectByteBuffer(void*, long)
0N/A //
0N/A private Direct$Type$Buffer(long addr, int cap) {
2984N/A super(-1, 0, cap, cap);
0N/A address = addr;
0N/A cleaner = null;
4352N/A att = null;
0N/A }
0N/A
0N/A#end[rw]
0N/A
0N/A // For memory-mapped buffers -- invoked by FileChannelImpl via reflection
0N/A //
2984N/A protected Direct$Type$Buffer$RW$(int cap, long addr,
2984N/A FileDescriptor fd,
2984N/A Runnable unmapper)
2984N/A {
0N/A#if[rw]
2984N/A super(-1, 0, cap, cap, fd);
0N/A address = addr;
0N/A cleaner = Cleaner.create(this, unmapper);
4352N/A att = null;
0N/A#else[rw]
2984N/A super(cap, addr, fd, unmapper);
0N/A#end[rw]
0N/A }
0N/A
0N/A#end[byte]
0N/A
0N/A // For duplicates and slices
0N/A //
0N/A Direct$Type$Buffer$RW$$BO$(DirectBuffer db, // package-private
0N/A int mark, int pos, int lim, int cap,
0N/A int off)
0N/A {
0N/A#if[rw]
0N/A super(mark, pos, lim, cap);
0N/A address = db.address() + off;
0N/A#if[byte]
0N/A cleaner = null;
0N/A#end[byte]
4352N/A att = db;
0N/A#else[rw]
0N/A super(db, mark, pos, lim, cap, off);
0N/A#end[rw]
0N/A }
0N/A
0N/A public $Type$Buffer slice() {
0N/A int pos = this.position();
0N/A int lim = this.limit();
0N/A assert (pos <= lim);
0N/A int rem = (pos <= lim ? lim - pos : 0);
0N/A int off = (pos << $LG_BYTES_PER_VALUE$);
0N/A assert (off >= 0);
0N/A return new Direct$Type$Buffer$RW$$BO$(this, -1, 0, rem, rem, off);
0N/A }
0N/A
0N/A public $Type$Buffer duplicate() {
0N/A return new Direct$Type$Buffer$RW$$BO$(this,
0N/A this.markValue(),
0N/A this.position(),
0N/A this.limit(),
0N/A this.capacity(),
0N/A 0);
0N/A }
0N/A
0N/A public $Type$Buffer asReadOnlyBuffer() {
0N/A#if[rw]
0N/A return new Direct$Type$BufferR$BO$(this,
0N/A this.markValue(),
0N/A this.position(),
0N/A this.limit(),
0N/A this.capacity(),
0N/A 0);
0N/A#else[rw]
0N/A return duplicate();
0N/A#end[rw]
0N/A }
0N/A
0N/A#if[rw]
0N/A
0N/A public long address() {
0N/A return address;
0N/A }
0N/A
0N/A private long ix(int i) {
0N/A return address + (i << $LG_BYTES_PER_VALUE$);
0N/A }
0N/A
0N/A public $type$ get() {
0N/A return $fromBits$($swap$(unsafe.get$Swaptype$(ix(nextGetIndex()))));
0N/A }
0N/A
0N/A public $type$ get(int i) {
0N/A return $fromBits$($swap$(unsafe.get$Swaptype$(ix(checkIndex(i)))));
0N/A }
0N/A
0N/A public $Type$Buffer get($type$[] dst, int offset, int length) {
0N/A#if[rw]
0N/A if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_TO_ARRAY_THRESHOLD) {
0N/A checkBounds(offset, length, dst.length);
0N/A int pos = position();
0N/A int lim = limit();
0N/A assert (pos <= lim);
0N/A int rem = (pos <= lim ? lim - pos : 0);
0N/A if (length > rem)
0N/A throw new BufferUnderflowException();
0N/A
523N/A#if[!byte]
0N/A if (order() != ByteOrder.nativeOrder())
0N/A Bits.copyTo$Memtype$Array(ix(pos), dst,
0N/A offset << $LG_BYTES_PER_VALUE$,
0N/A length << $LG_BYTES_PER_VALUE$);
0N/A else
523N/A#end[!byte]
523N/A Bits.copyToArray(ix(pos), dst, arrayBaseOffset,
523N/A offset << $LG_BYTES_PER_VALUE$,
523N/A length << $LG_BYTES_PER_VALUE$);
0N/A position(pos + length);
0N/A } else {
0N/A super.get(dst, offset, length);
0N/A }
0N/A return this;
0N/A#else[rw]
0N/A throw new ReadOnlyBufferException();
0N/A#end[rw]
0N/A }
0N/A
0N/A#end[rw]
0N/A
0N/A public $Type$Buffer put($type$ x) {
0N/A#if[rw]
0N/A unsafe.put$Swaptype$(ix(nextPutIndex()), $swap$($toBits$(x)));
0N/A return this;
0N/A#else[rw]
0N/A throw new ReadOnlyBufferException();
0N/A#end[rw]
0N/A }
0N/A
0N/A public $Type$Buffer put(int i, $type$ x) {
0N/A#if[rw]
0N/A unsafe.put$Swaptype$(ix(checkIndex(i)), $swap$($toBits$(x)));
0N/A return this;
0N/A#else[rw]
0N/A throw new ReadOnlyBufferException();
0N/A#end[rw]
0N/A }
0N/A
0N/A public $Type$Buffer put($Type$Buffer src) {
0N/A#if[rw]
0N/A if (src instanceof Direct$Type$Buffer$BO$) {
0N/A if (src == this)
0N/A throw new IllegalArgumentException();
0N/A Direct$Type$Buffer$RW$$BO$ sb = (Direct$Type$Buffer$RW$$BO$)src;
0N/A
0N/A int spos = sb.position();
0N/A int slim = sb.limit();
0N/A assert (spos <= slim);
0N/A int srem = (spos <= slim ? slim - spos : 0);
0N/A
0N/A int pos = position();
0N/A int lim = limit();
0N/A assert (pos <= lim);
0N/A int rem = (pos <= lim ? lim - pos : 0);
0N/A
0N/A if (srem > rem)
0N/A throw new BufferOverflowException();
0N/A unsafe.copyMemory(sb.ix(spos), ix(pos), srem << $LG_BYTES_PER_VALUE$);
0N/A sb.position(spos + srem);
0N/A position(pos + srem);
0N/A } else if (src.hb != null) {
0N/A
0N/A int spos = src.position();
0N/A int slim = src.limit();
0N/A assert (spos <= slim);
0N/A int srem = (spos <= slim ? slim - spos : 0);
0N/A
0N/A put(src.hb, src.offset + spos, srem);
0N/A src.position(spos + srem);
0N/A
0N/A } else {
0N/A super.put(src);
0N/A }
0N/A return this;
0N/A#else[rw]
0N/A throw new ReadOnlyBufferException();
0N/A#end[rw]
0N/A }
0N/A
0N/A public $Type$Buffer put($type$[] src, int offset, int length) {
0N/A#if[rw]
0N/A if ((length << $LG_BYTES_PER_VALUE$) > Bits.JNI_COPY_FROM_ARRAY_THRESHOLD) {
0N/A checkBounds(offset, length, src.length);
0N/A int pos = position();
0N/A int lim = limit();
0N/A assert (pos <= lim);
0N/A int rem = (pos <= lim ? lim - pos : 0);
0N/A if (length > rem)
0N/A throw new BufferOverflowException();
0N/A
523N/A#if[!byte]
0N/A if (order() != ByteOrder.nativeOrder())
0N/A Bits.copyFrom$Memtype$Array(src, offset << $LG_BYTES_PER_VALUE$,
0N/A ix(pos), length << $LG_BYTES_PER_VALUE$);
0N/A else
523N/A#end[!byte]
523N/A Bits.copyFromArray(src, arrayBaseOffset, offset << $LG_BYTES_PER_VALUE$,
523N/A ix(pos), length << $LG_BYTES_PER_VALUE$);
0N/A position(pos + length);
0N/A } else {
0N/A super.put(src, offset, length);
0N/A }
0N/A return this;
0N/A#else[rw]
0N/A throw new ReadOnlyBufferException();
0N/A#end[rw]
0N/A }
0N/A
0N/A public $Type$Buffer compact() {
0N/A#if[rw]
0N/A int pos = position();
0N/A int lim = limit();
0N/A assert (pos <= lim);
0N/A int rem = (pos <= lim ? lim - pos : 0);
0N/A
0N/A unsafe.copyMemory(ix(pos), ix(0), rem << $LG_BYTES_PER_VALUE$);
0N/A position(rem);
0N/A limit(capacity());
721N/A discardMark();
0N/A return this;
0N/A#else[rw]
0N/A throw new ReadOnlyBufferException();
0N/A#end[rw]
0N/A }
0N/A
0N/A public boolean isDirect() {
0N/A return true;
0N/A }
0N/A
0N/A public boolean isReadOnly() {
0N/A return {#if[rw]?false:true};
0N/A }
0N/A
0N/A
0N/A#if[char]
0N/A
0N/A public String toString(int start, int end) {
0N/A if ((end > limit()) || (start > end))
0N/A throw new IndexOutOfBoundsException();
0N/A try {
0N/A int len = end - start;
0N/A char[] ca = new char[len];
0N/A CharBuffer cb = CharBuffer.wrap(ca);
0N/A CharBuffer db = this.duplicate();
0N/A db.position(start);
0N/A db.limit(end);
0N/A cb.put(db);
0N/A return new String(ca);
0N/A } catch (StringIndexOutOfBoundsException x) {
0N/A throw new IndexOutOfBoundsException();
0N/A }
0N/A }
0N/A
0N/A
0N/A // --- Methods to support CharSequence ---
0N/A
571N/A public CharBuffer subSequence(int start, int end) {
0N/A int pos = position();
0N/A int lim = limit();
0N/A assert (pos <= lim);
0N/A pos = (pos <= lim ? pos : lim);
0N/A int len = lim - pos;
0N/A
0N/A if ((start < 0) || (end > len) || (start > end))
0N/A throw new IndexOutOfBoundsException();
1108N/A return new DirectCharBuffer$RW$$BO$(this,
1108N/A -1,
1108N/A pos + start,
1108N/A pos + end,
1108N/A capacity(),
1108N/A offset);
0N/A }
0N/A
0N/A#end[char]
0N/A
0N/A
0N/A
0N/A#if[!byte]
0N/A
0N/A public ByteOrder order() {
0N/A#if[boS]
0N/A return ((ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
0N/A ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
0N/A#end[boS]
0N/A#if[boU]
0N/A return ((ByteOrder.nativeOrder() != ByteOrder.BIG_ENDIAN)
0N/A ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN);
0N/A#end[boU]
0N/A }
0N/A
0N/A#end[!byte]
0N/A
0N/A
0N/A
0N/A#if[byte]
0N/A
0N/A byte _get(int i) { // package-private
0N/A return unsafe.getByte(address + i);
0N/A }
0N/A
0N/A void _put(int i, byte b) { // package-private
0N/A#if[rw]
0N/A unsafe.putByte(address + i, b);
0N/A#else[rw]
0N/A throw new ReadOnlyBufferException();
0N/A#end[rw]
0N/A }
0N/A
0N/A // #BIN
0N/A //
0N/A // Binary-data access methods for short, char, int, long, float,
0N/A // and double will be inserted here
0N/A
0N/A#end[byte]
0N/A
0N/A}