/* * @(#) $(JCGO)/goclsp/vm/java/nio/VMDirectByteBuffer.java -- * VM specific methods for native direct byte buffer implementation. ** * Project: JCGO (http://www.ivmaisoft.com/jcgo/) * Copyright (C) 2001-2012 Ivan Maidanski <ivmai@ivmaisoft.com> * All rights reserved. ** * Class specification origin: GNU Classpath v0.93 vm/reference */ /* * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. ** * This software 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 (GPL) for more details. ** * Linking this library statically or dynamically with other modules is * making a combined work based on this library. Thus, the terms and * conditions of the GNU General Public License cover the whole * combination. ** * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent * modules, and to copy and distribute the resulting executable under * terms of your choice, provided that you also meet, for each linked * independent module, the terms and conditions of the license of that * module. An independent module is a module which is not derived from * or based on this library. If you modify this library, you may extend * this exception to your version of the library, but you are not * obligated to do so. If you do not wish to do so, delete this * exception statement from your version. */ package java.nio; import gnu.classpath.Pointer; final class VMDirectByteBuffer /* hard-coded class name */ { private static final class DirectPointer extends Pointer { final transient Object vmdata; final int offset; DirectPointer(Object vmdata, int offset) { this.vmdata = vmdata; this.offset = offset; } } static { if ((new DirectPointer(null, 0)).vmdata != null) /* hack */ { Object buf = newDirectByteBuffer0X(null, 0L); /* hack */ getDirectBufferAddressVmData0X(buf); /* hack */ getDirectBufferAddressOffset0X(buf); /* hack */ getDirectBufferCapacity0X(buf); /* hack */ } } private VMDirectByteBuffer() {} static Pointer allocate(int capacity) { if (capacity < 0) throw new NegativeArraySizeException(); Object vmdata = allocate0(capacity != 0 ? capacity : 1); if (vmdata == null) throw new OutOfMemoryError("cannot allocate direct buffer"); return new DirectPointer(vmdata, 0); } static void free(Pointer address) { free0(((DirectPointer) address).vmdata); } static byte get(Pointer address, int index) { byte[] dst = new byte[1]; DirectPointer ptr = (DirectPointer) address; getRegion0(ptr.vmdata, dst, 0, 1, ptr.offset + index); return dst[0]; } static void get(Pointer address, int index, byte[] dst, int offset, int length) { if (length > 0) { DirectPointer ptr = (DirectPointer) address; getRegion0(ptr.vmdata, dst, offset, length, ptr.offset + index); } } static void put(Pointer address, int index, byte value) { DirectPointer ptr = (DirectPointer) address; putRegion0(ptr.vmdata, new byte[] { value }, 0, 1, ptr.offset + index); } static void put(Pointer address, int index, byte[] src, int offset, int length) { if (length > 0) { DirectPointer ptr = (DirectPointer) address; putRegion0(ptr.vmdata, src, offset, length, ptr.offset + index); } } static Pointer adjustAddress(Pointer address, int offset) { DirectPointer ptr = (DirectPointer) address; return new DirectPointer(ptr.vmdata, ptr.offset + offset); } static void shiftDown(Pointer address, int dstOffset, int srcOffset, int count) { if (count > 0 && dstOffset != srcOffset) { DirectPointer ptr = (DirectPointer) address; moveRegion0(ptr.vmdata, ptr.offset + dstOffset, ptr.offset + srcOffset, count); } } static final Object newDirectByteBuffer0X(Object vmdata, long capacity) { /* called from native code */ if (vmdata == null) throw new NullPointerException(); if (capacity < 0L) throw new NegativeArraySizeException(); int len = capacity < (long) (-1 >>> 1) ? (int) capacity : -1 >>> 1; return new DirectByteBufferImpl.ReadWrite(null, new DirectPointer(vmdata, 0), len, len, 0); } static final Object getDirectBufferAddressVmData0X(Object bufObj) throws ClassCastException { /* called from native code */ Pointer address = ((Buffer) bufObj).address; return address instanceof DirectPointer ? ((DirectPointer) address).vmdata : null; } static final int getDirectBufferAddressOffset0X(Object bufObj) throws ClassCastException { /* called from native code */ return ((DirectPointer) ((Buffer) bufObj).address).offset; } static final long getDirectBufferCapacity0X(Object bufObj) throws ClassCastException { /* called from native code */ Buffer buf = (Buffer) bufObj; return buf.address != null ? buf.capacity() : -1; } private static native Object allocate0(int capacity); /* JVM-core */ private static native int getRegion0(Object vmdata, byte[] dst, int offset, int len, int index); /* JVM-core */ private static native int putRegion0(Object vmdata, byte[] src, int offset, int len, int index); /* JVM-core */ private static native int moveRegion0(Object vmdata, int dstIndex, int srcIndex, int len); /* JVM-core */ private static native int free0(Object vmdata); /* JVM-core */ }