/* * Copyright (c) 2010-2023 JogAmp Community. All rights reserved. * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed or intended for use * in the design, construction, operation or maintenance of any nuclear * facility. * * Sun gratefully acknowledges that this software was originally authored * and developed by Kenneth Bradley Russell and Christopher John Kline. */ package com.jogamp.common.nio; import java.nio.*; /** * @author Kenneth Russel, Sven Gothel, Michael Bien, et al. */ public class StructAccessor { private final ByteBuffer bb; /** Create a new instance. The {@link ByteBuffer} will be {@link ByteBuffer#rewind()} and native-order to be used with native code set. */ public StructAccessor(final ByteBuffer bb) { this.bb = bb.order(ByteOrder.nativeOrder()); this.bb.rewind(); } /** Return the underlying native direct ByteBuffer */ public final ByteBuffer getBuffer() { return bb; } /** Returns the native address of the underlying native ByteBuffer. */ public final long getDirectBufferAddress() { return Buffers.getDirectBufferAddressImpl(bb); } /** * Returns a slice of the current ByteBuffer starting at the * specified byte offset and extending the specified number of * bytes. Note that this method is not thread-safe with respect to * the other methods in this class. */ public final ByteBuffer slice(final int byteOffset, final int byteLength) { bb.position(byteOffset); bb.limit(byteOffset + byteLength); final ByteBuffer newBuf = bb.slice().order(bb.order()); // slice and duplicate may change byte order bb.position(0); bb.limit(bb.capacity()); return newBuf; } /** Retrieves the byte at the specified byteOffset. */ public final byte getByteAt(final int byteOffset) { return bb.get(byteOffset); } /** Puts a byte at the specified byteOffset. */ public final void setByteAt(final int byteOffset, final byte v) { bb.put(byteOffset, v); } /** Retrieves the boolean at the specified byteOffset. */ public final boolean getBooleanAt(final int byteOffset) { return (byte)0 != bb.get(byteOffset); } /** Puts a boolean at the specified byteOffset. */ public final void setBooleanAt(final int byteOffset, final boolean v) { bb.put(byteOffset, v?(byte)1:(byte)0); } /** Retrieves the char at the specified byteOffset. */ public final char getCharAt(final int byteOffset) { return bb.getChar(byteOffset); } /** Puts a char at the specified byteOffset. */ public final void setCharAt(final int byteOffset, final char v) { bb.putChar(byteOffset, v); } /** Retrieves the short at the specified byteOffset. */ public final short getShortAt(final int byteOffset) { return bb.getShort(byteOffset); } /** Puts a short at the specified byteOffset. */ public final void setShortAt(final int byteOffset, final short v) { bb.putShort(byteOffset, v); } /** Retrieves the int at the specified byteOffset. */ public final int getIntAt(final int byteOffset) { return bb.getInt(byteOffset); } /** Puts a int at the specified byteOffset. */ public final void setIntAt(final int byteOffset, final int v) { bb.putInt(byteOffset, v); } /** Retrieves the int at the specified byteOffset. */ public final int getIntAt(final int byteOffset, final int nativeSizeInBytes) { switch(nativeSizeInBytes) { case 2: return bb.getShort(byteOffset) & 0x0000FFFF ; case 4: return bb.getInt(byteOffset); case 8: return (int) ( bb.getLong(byteOffset) & 0x00000000FFFFFFFFL ) ; default: throw new InternalError("invalid nativeSizeInBytes "+nativeSizeInBytes); } } /** Puts a int at the specified byteOffset. */ public final void setIntAt(final int byteOffset, final int v, final int nativeSizeInBytes) { switch(nativeSizeInBytes) { case 2: bb.putShort(byteOffset, (short) ( v & 0x0000FFFF ) ); break; case 4: bb.putInt(byteOffset, v); break; case 8: bb.putLong(byteOffset, v & 0x00000000FFFFFFFFL ); break; default: throw new InternalError("invalid nativeSizeInBytes "+nativeSizeInBytes); } } /** Retrieves the float at the specified byteOffset. */ public final float getFloatAt(final int byteOffset) { return bb.getFloat(byteOffset); } /** Puts a float at the specified byteOffset. */ public final void setFloatAt(final int byteOffset, final float v) { bb.putFloat(byteOffset, v); } /** Retrieves the double at the specified byteOffset. */ public final double getDoubleAt(final int byteOffset) { return bb.getDouble(byteOffset); } /** Puts a double at the specified byteOffset. */ public final void setDoubleAt(final int byteOffset, final double v) { bb.putDouble(byteOffset, v); } /** Retrieves the long at the specified byteOffset. */ public final long getLongAt(final int byteOffset) { return bb.getLong(byteOffset); } /** Puts a long at the specified byteOffset. */ public final void setLongAt(final int byteOffset, final long v) { bb.putLong(byteOffset, v); } /** Retrieves the long at the specified byteOffset. */ public final long getLongAt(final int byteOffset, final int nativeSizeInBytes) { switch(nativeSizeInBytes) { case 4: return bb.getInt(byteOffset) & 0x00000000FFFFFFFFL; case 8: return bb.getLong(byteOffset); default: throw new InternalError("invalid nativeSizeInBytes "+nativeSizeInBytes); } } /** Puts a long at the specified byteOffset. */ public final void setLongAt(final int byteOffset, final long v, final int nativeSizeInBytes) { switch(nativeSizeInBytes) { case 4: bb.putInt(byteOffset, (int) ( v & 0x00000000FFFFFFFFL ) ); break; case 8: bb.putLong(byteOffset, v); break; default: throw new InternalError("invalid nativeSizeInBytes "+nativeSizeInBytes); } } public final void setBytesAt(int byteOffset, final byte[] v) { for (int i = 0; i < v.length; i++) { bb.put(byteOffset++, v[i]); } } public final byte[] getBytesAt(int byteOffset, final byte[] v) { for (int i = 0; i < v.length; i++) { v[i] = bb.get(byteOffset++); } return v; } public final void setBooleansAt(int byteOffset, final boolean[] v) { for (int i = 0; i < v.length; i++) { bb.put(byteOffset++, v[i]?(byte)1:(byte)0); } } public final boolean[] getBooleansAt(int byteOffset, final boolean[] v) { for (int i = 0; i < v.length; i++) { v[i] = (byte)0 != bb.get(byteOffset++); } return v; } public final void setCharsAt(int byteOffset, final char[] v) { for (int i = 0; i < v.length; i++, byteOffset+=2) { bb.putChar(byteOffset, v[i]); } } public final char[] getCharsAt(int byteOffset, final char[] v) { for (int i = 0; i < v.length; i++, byteOffset+=2) { v[i] = bb.getChar(byteOffset); } return v; } public final void setShortsAt(int byteOffset, final short[] v) { for (int i = 0; i < v.length; i++, byteOffset+=2) { bb.putShort(byteOffset, v[i]); } } public final short[] getShortsAt(int byteOffset, final short[] v) { for (int i = 0; i < v.length; i++, byteOffset+=2) { v[i] = bb.getShort(byteOffset); } return v; } public final void setIntsAt(int byteOffset, final int[] v) { for (int i = 0; i < v.length; i++, byteOffset+=4) { bb.putInt(byteOffset, v[i]); } } public final int[] getIntsAt(int byteOffset, final int[] v) { for (int i = 0; i < v.length; i++, byteOffset+=4) { v[i] = bb.getInt(byteOffset); } return v; } public final void setFloatsAt(int byteOffset, final float[] v) { for (int i = 0; i < v.length; i++, byteOffset+=4) { bb.putFloat(byteOffset, v[i]); } } public final float[] getFloatsAt(int byteOffset, final float[] v) { for (int i = 0; i < v.length; i++, byteOffset+=4) { v[i] = bb.getFloat(byteOffset); } return v; } public final void setDoublesAt(int byteOffset, final double[] v) { for (int i = 0; i < v.length; i++, byteOffset+=8) { bb.putDouble(byteOffset, v[i]); } } public final double[] getDoublesAt(int byteOffset, final double[] v) { for (int i = 0; i < v.length; i++, byteOffset+=8) { v[i] = bb.getDouble(byteOffset); } return v; } public final void setLongsAt(int byteOffset, final long[] v) { for (int i = 0; i < v.length; i++, byteOffset+=8) { bb.putLong(byteOffset, v[i]); } } public final long[] getLongsAt(int byteOffset, final long[] v) { for (int i = 0; i < v.length; i++, byteOffset+=8) { v[i] = bb.getLong(byteOffset); } return v; } }