jnr.ffi.Struct Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jnr-ffi Show documentation
Show all versions of jnr-ffi Show documentation
A library for invoking native functions from java
/*
* Copyright (C) 2008-2010 Wayne Meissner
*
* This file is part of the JNR project.
*
* Licensed 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.
*/
/*
* Some of the design and code of this class is from the javolution project.
*
* Copyright (C) 2006 - Javolution (http://javolution.org/)
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software is
* freely granted, provided that this notice is preserved.
*/
package jnr.ffi;
import jnr.ffi.provider.ParameterFlags;
import jnr.ffi.util.EnumMapper;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.nio.charset.Charset;
/**
* Representation of C structures in java.
*
* Note: This class is not threadsafe.
*/
public abstract class Struct {
static final Charset ASCII = Charset.forName("ASCII");
static final Charset UTF8 = Charset.forName("UTF-8");
static final class Info {
private final Runtime runtime;
private jnr.ffi.Pointer memory = null;
Struct enclosing = null;
int offset = 0; // offset within enclosing Struct
int size = 0;
int minAlign = 1;
boolean isUnion = false;
boolean resetIndex = false;
public Info(Runtime runtime) {
this.runtime = runtime;
}
public final jnr.ffi.Pointer getMemory(int flags) {
return enclosing != null ? enclosing.__info.getMemory(flags) : memory != null ? memory : (memory = allocateMemory(flags));
}
public final jnr.ffi.Pointer getMemory() {
return getMemory(ParameterFlags.TRANSIENT);
}
final boolean isDirect() {
return (enclosing != null && enclosing.__info.isDirect()) || (memory != null && memory.isDirect());
}
final int size() {
return size;
}
final int getMinimumAlignment() {
return minAlign;
}
private jnr.ffi.Pointer allocateMemory(int flags) {
if (ParameterFlags.isDirect(flags)) {
return runtime.getMemoryManager().allocateDirect(size(), true);
} else {
return runtime.getMemoryManager().allocate(size());
}
}
public final void useMemory(jnr.ffi.Pointer io) {
this.memory = io;
}
protected final int addField(int sizeBits, int alignBits, Offset offset) {
this.size = Math.max(this.size, offset.intValue() + (sizeBits >> 3));
this.minAlign = Math.max(this.minAlign, alignBits >> 3);
return offset.intValue();
}
protected final int addField(int sizeBits, int alignBits) {
final int off = resetIndex ? 0 : align(this.size, alignBits >> 3);
this.size = Math.max(this.size, off + (sizeBits >> 3));
this.minAlign = Math.max(this.minAlign, alignBits >> 3);
return off;
}
}
final Info __info;
/**
* Creates a new {@code Struct}.
*
* @param runtime The current runtime.
*/
protected Struct(Runtime runtime) {
this.__info = new Info(runtime);
}
/**
* Creates a new Struct.
*
* @param isUnion if this Struct is a Union
*/
Struct(Runtime runtime, final boolean isUnion) {
this(runtime);
__info.resetIndex = isUnion;
}
public final Runtime getRuntime() {
return __info.runtime;
}
/**
* Uses the specified memory address as the backing store for this structure.
*
* @param address the native memory area.
*/
public final void useMemory(jnr.ffi.Pointer address) {
__info.useMemory(address);
}
public static jnr.ffi.Pointer getMemory(Struct struct) {
return struct.__info.getMemory(0);
}
public static jnr.ffi.Pointer getMemory(Struct struct, int flags) {
return struct.__info.getMemory(flags);
}
public static int size(Struct struct) {
return struct.__info.size();
}
public static int alignment(Struct struct) {
return struct.__info.getMinimumAlignment();
}
public static boolean isDirect(Struct struct) {
return struct.__info.isDirect();
}
private static int align(int offset, int align) {
return (offset + align - 1) & ~(align - 1);
}
@SuppressWarnings("unchecked")
public static T[] arrayOf(Runtime runtime, Class type, int length) {
try {
T[] array = (T[]) Array.newInstance(type, length);
Constructor c = type.getConstructor(Runtime.class);
for (int i = 0; i < length; ++i) {
array[i] = c.newInstance(runtime);
}
if (array.length > 0) {
final int structSize = align(Struct.size(array[0]), Struct.alignment(array[0]));
jnr.ffi.Pointer memory = runtime.getMemoryManager().allocateDirect(structSize * length);
for (int i = 0; i < array.length; ++i) {
array[i].useMemory(memory.slice(structSize * i, structSize));
}
}
return array;
} catch (RuntimeException ex) {
throw ex;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
/**
* Returns a human readable {@link java.lang.String} representation of the structure.
*
* @return a {@code String} representation of this structure.
*/
@Override
public java.lang.String toString() {
StringBuilder sb = new StringBuilder();
java.lang.reflect.Field[] fields = getClass().getDeclaredFields();
sb.append(getClass().getSimpleName()).append(" { \n");
final java.lang.String fieldPrefix = " ";
for (java.lang.reflect.Field field : fields) {
try {
sb.append(fieldPrefix);
sb.append(field.getName()).append(" = ");
sb.append(field.get(this).toString());
sb.append("\n");
} catch (Throwable ex) {
throw new RuntimeException(ex);
}
}
sb.append("}\n");
return sb.toString();
}
public static final class Offset extends java.lang.Number {
private final int offset;
public Offset(int offset) {
this.offset = offset;
}
@Override
public int intValue() {
return offset;
}
@Override
public long longValue() {
return offset;
}
@Override
public float floatValue() {
return offset;
}
@Override
public double doubleValue() {
return offset;
}
}
/**
* Interface all Struct members must implement.
*/
protected abstract class Member {
/**
* Gets the {@code Struct} this {@code Member} is a member of.
*
* @return a {@code Struct}.
*/
abstract Struct struct();
/**
* Gets the memory object used to store this {@code Member}
*
* @return a {@code Pointer}
*/
abstract jnr.ffi.Pointer getMemory();
/**
* Gets the offset within the structure for this field.
*
* @return the offset within the structure for this field.
*/
abstract long offset();
}
/**
* Starts an array construction session
*/
protected final void arrayBegin() {
__info.resetIndex = false;
}
/**
* Ends an array construction session
*/
protected final void arrayEnd() {
__info.resetIndex = __info.isUnion;
}
/**
* Creates an array of Member instances.
*
* @param The type of the Member subclass to create.
* @param array the array to store the instances in
* @return the array that was passed in
*/
@SuppressWarnings("unchecked")
protected T[] array(T[] array) {
arrayBegin();
try {
Class> arrayClass = array.getClass().getComponentType();
Constructor> ctor = arrayClass.getDeclaredConstructor(new Class[] { arrayClass.getEnclosingClass() });
Object[] parameters = { Struct.this };
for (int i = 0; i < array.length; ++i) {
array[i] = (T) ctor.newInstance(parameters);
}
} catch (Exception ex) {
throw new RuntimeException(ex);
}
arrayEnd();
return array;
}
/**
* Creates an array of Signed8 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Signed8[] array(Signed8[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Signed8();
}
arrayEnd();
return array;
}
/**
* Creates an array of Unsigned8 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Unsigned8[] array(Unsigned8[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Unsigned8();
}
arrayEnd();
return array;
}
/**
* Creates an array of Signed16 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Signed16[] array(Signed16[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Signed16();
}
arrayEnd();
return array;
}
/**
* Creates an array of Unsigned16 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Unsigned16[] array(Unsigned16[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Unsigned16();
}
arrayEnd();
return array;
}
/**
* Creates an array of Signed32 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Signed32[] array(Signed32[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Signed32();
}
arrayEnd();
return array;
}
/**
* Creates an array of Unsigned32 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Unsigned32[] array(Unsigned32[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Unsigned32();
}
arrayEnd();
return array;
}
/**
* Creates an array of Signed64 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Signed64[] array(Signed64[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Signed64();
}
arrayEnd();
return array;
}
/**
* Creates an array of Unsigned64 instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Unsigned64[] array(Unsigned64[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Unsigned64();
}
arrayEnd();
return array;
}
/**
* Creates an array of SignedLong instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final SignedLong[] array(SignedLong[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new SignedLong();
}
arrayEnd();
return array;
}
/**
* Creates an array of UnsignedLong instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final UnsignedLong[] array(UnsignedLong[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new UnsignedLong();
}
arrayEnd();
return array;
}
/**
* Creates an array of Float instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Float[] array(Float[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Float();
}
arrayEnd();
return array;
}
/**
* Creates an array of Double instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Double[] array(Double[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Double();
}
arrayEnd();
return array;
}
/**
* Creates an array of Address instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Address[] array(Address[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Address();
}
arrayEnd();
return array;
}
/**
* Creates an array of Pointer instances.
*
* @param array the array to store the instances in
* @return the array that was passed in
*/
protected final Pointer[] array(Pointer[] array) {
arrayBegin();
for (int i = 0; i < array.length; ++i) {
array[i] = new Pointer();
}
arrayEnd();
return array;
}
protected final T inner(T struct) {
int off = align(__info.size, struct.__info.getMinimumAlignment());
struct.__info.enclosing = this;
struct.__info.offset = off;
__info.size = off + struct.__info.size;
return struct;
}
/**
* Base implementation of Member
*/
protected abstract class AbstractMember extends Member {
private final int offset;
protected AbstractMember(int size) {
this(size, size);
}
protected AbstractMember(int size, int align, Offset offset) {
this.offset = __info.addField(size, align, offset);
}
protected AbstractMember(int size, int align) {
this.offset = __info.addField(size, align);
}
protected AbstractMember(NativeType type) {
final Type t = getRuntime().findType(type);
this.offset = __info.addField(t.size() * 8, t.alignment() * 8);
}
protected AbstractMember(NativeType type, Offset offset) {
final Type t = getRuntime().findType(type);
this.offset = __info.addField(t.size() * 8, t.alignment() * 8, offset);
}
public final jnr.ffi.Pointer getMemory() {
return __info.getMemory();
}
/**
* Gets the Struct this Member is a member of.
*
* @return a Struct.
*/
public final Struct struct() {
return Struct.this;
}
/**
* Gets the offset within the structure for this field.
*/
public final long offset() {
return offset + __info.offset;
}
}
/**
* Base class for Boolean fields
*/
protected abstract class AbstractBoolean extends AbstractMember {
protected AbstractBoolean(NativeType type) {
super(type);
}
protected AbstractBoolean(NativeType type, Offset offset) {
super(type, offset);
}
/**
* Gets the value for this field.
*
* @return a boolean.
*/
public abstract boolean get();
/**
* Sets the field to a new value.
*
* @param value The new value.
*/
public abstract void set(boolean value);
/**
* Returns a string representation of this Address
.
*
* @return a string representation of this Address
.
*/
@Override
public java.lang.String toString() {
return java.lang.Boolean.toString(get());
}
}
/**
* A normal C boolean - 1 byte in size
*/
public final class Boolean extends AbstractBoolean {
public Boolean() {
super(NativeType.SCHAR);
}
public final boolean get() {
return (getMemory().getByte(offset()) & 0x1) != 0;
}
public final void set(boolean value) {
getMemory().putByte(offset(), (byte) (value ? 1 : 0));
}
}
/**
* A Windows BOOL - 4 bytes
*/
public final class WBOOL extends AbstractBoolean {
public WBOOL() {
super(NativeType.SINT);
}
public final boolean get() {
return (getMemory().getInt(offset()) & 0x1) != 0;
}
public final void set(boolean value) {
getMemory().putInt(offset(), value ? 1 : 0);
}
}
/**
* Base class for all Number structure fields.
*/
public abstract class NumberField extends Member {
/**
* Offset from the start of the Struct memory this field is located at.
*/
private final int offset;
protected final Type type;
protected NumberField(NativeType type) {
Type t = this.type = getRuntime().findType(type);
this.offset = __info.addField(t.size() * 8, t.alignment() * 8);
}
protected NumberField(NativeType type, Offset offset) {
Type t = this.type = getRuntime().findType(type);
this.offset = __info.addField(t.size() * 8, t.alignment() * 8, offset);
}
protected NumberField(TypeAlias type) {
Type t = this.type = getRuntime().findType(type);
this.offset = __info.addField(t.size() * 8, t.alignment() * 8);
}
protected NumberField(TypeAlias type, Offset offset) {
Type t = this.type = getRuntime().findType(type);
this.offset = __info.addField(t.size() * 8, t.alignment() * 8, offset);
}
public final jnr.ffi.Pointer getMemory() {
return __info.getMemory();
}
/**
* Gets the Struct this Member is in.
*
* @return a Struct.
*/
public final Struct struct() {
return Struct.this;
}
/**
* Gets the offset within the structure for this field.
*/
public final long offset() {
return offset + __info.offset;
}
/**
* Sets the field to a new value.
*
* @param value The new value.
*/
public abstract void set(java.lang.Number value);
/**
* Returns an {@code float} representation of this Number.
*
* @return an {@code float} value for this Number.
*/
public double doubleValue() {
return (double) longValue();
}
/**
* Returns an {@code float} representation of this Number.
*
* @return an {@code float} value for this Number.
*/
public float floatValue() {
return (float) intValue();
}
/**
* Returns a {@code byte} representation of this Number.
*
* @return a {@code byte} value for this Number.
*/
public byte byteValue() {
return (byte) intValue();
}
/**
* Returns a {@code short} representation of this Number.
*
* @return a {@code short} value for this Number.
*/
public short shortValue() {
return (short) intValue();
}
/**
* Returns a {@code int} representation of this Number.
*
* @return a {@code int} value for this Number.
*/
public abstract int intValue();
/**
* Returns a {@code long} representation of this Number.
*
* @return a {@code long} value for this Number.
*/
public long longValue() {
return intValue();
}
/**
* Returns a string representation of this Address
.
*
* @return a string representation of this Address
.
*/
@Override
public java.lang.String toString() {
return java.lang.Integer.toString(intValue(), 10);
}
}
public abstract class IntegerAlias extends NumberField {
IntegerAlias(TypeAlias type) {
super(type);
}
IntegerAlias(TypeAlias type, Offset offset) {
super(type, offset);
}
@Override
public void set(Number value) {
getMemory().putInt(type, offset(), value.longValue());
}
public void set(long value) {
getMemory().putInt(type, offset(), value);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
return getMemory().getInt(type, offset());
}
@Override
public int intValue() {
return (int) get();
}
@Override
public long longValue() {
return get();
}
}
/**
* An 8 bit signed integer
*/
public class Signed8 extends NumberField {
/**
* Creates a new 8 bit integer field.
*/
public Signed8() {
super(NativeType.SCHAR);
}
/**
* Creates a new 8 bit integer field at a specific offset
*
* @param offset The offset within the memory area
*/
public Signed8(Offset offset) {
super(NativeType.SCHAR, offset);
}
/**
* Gets the value for this field.
*
* @return a byte.
*/
public final byte get() {
return getMemory().getByte(offset());
}
/**
* Sets the value for this field.
*
* @param value the 8 bit value to set.
*/
public final void set(byte value) {
getMemory().putByte(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putByte(offset(), value.byteValue());
}
/**
* Returns a java byte representation of this field.
*
* @return a java byte value for this field.
*/
@Override
public final byte byteValue() {
return get();
}
/**
* Returns a java short representation of this field.
*
* @return a java short value for this field.
*/
@Override
public final short shortValue() {
return get();
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* An 8 bit unsigned integer
*/
public class Unsigned8 extends NumberField {
/**
* Creates a new 8 bit unsigned integer field.
*/
public Unsigned8() {
super(NativeType.UCHAR);
}
/**
* Creates a new 8 bit unsigned integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Unsigned8(Offset offset) {
super(NativeType.UCHAR, offset);
}
/**
* Gets the value for this field.
*
* @return a byte.
*/
public final short get() {
short value = getMemory().getByte(offset());
return value < 0 ? (short) ((value & 0x7F) + 0x80) : value;
}
/**
* Sets the value for this field.
*
* @param value the 8 bit value to set.
*/
public final void set(short value) {
getMemory().putByte(offset(), (byte) value);
}
public void set(java.lang.Number value) {
getMemory().putByte(offset(), value.byteValue());
}
/**
* Returns a java short representation of this field.
*
* @return a java short value for this field.
*/
@Override
public final short shortValue() {
return get();
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* A 16 bit signed integer field.
*/
public class Signed16 extends NumberField {
/**
* Creates a new 16 bit integer field.
*/
public Signed16() {
super(NativeType.SSHORT);
}
/**
* Creates a new 16 bit signed integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Signed16(Offset offset) {
super(NativeType.SSHORT, offset);
}
/**
* Gets the value for this field.
*
* @return a short.
*/
public final short get() {
return getMemory().getShort(offset());
}
/**
* Sets the value for this field.
*
* @param value the 16 bit value to set.
*/
public final void set(short value) {
getMemory().putShort(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putShort(offset(), value.shortValue());
}
/**
* Returns a java short representation of this field.
*
* @return a java short value for this field.
*/
@Override
public final short shortValue() {
return get();
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* A 16 bit signed integer field.
*/
public class Unsigned16 extends NumberField {
/**
* Creates a new 16 bit integer field.
*/
public Unsigned16() {
super(NativeType.USHORT);
}
/**
* Creates a new 16 bit unsigned integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Unsigned16(Offset offset) {
super(NativeType.USHORT, offset);
}
/**
* Gets the value for this field.
*
* @return a short.
*/
public final int get() {
int value = getMemory().getShort(offset());
return value < 0 ? (int)((value & 0x7FFF) + 0x8000) : value;
}
/**
* Sets the value for this field.
*
* @param value the 16 bit unsigned value to set.
*/
public final void set(int value) {
getMemory().putShort(offset(), (short) value);
}
public void set(Number value) {
getMemory().putShort(offset(), value.shortValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* A 32 bit signed integer field.
*/
public class Signed32 extends NumberField {
/**
* Creates a new 32 bit integer field.
*/
public Signed32() {
super(NativeType.SINT);
}
/**
* Creates a new 32 bit signed integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Signed32(Offset offset) {
super(NativeType.SINT, offset);
}
/**
* Gets the value for this field.
*
* @return a int.
*/
public final int get() {
return getMemory().getInt(offset());
}
/**
* Sets the value for this field.
*
* @param value the 32 bit value to set.
*/
public final void set(int value) {
getMemory().putInt(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putInt(offset(), value.intValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return get();
}
}
/**
* A 32 bit signed integer field.
*/
public class Unsigned32 extends NumberField {
/**
* Creates a new 32 bit integer field.
*/
public Unsigned32() {
super(NativeType.UINT);
}
/**
* Creates a new 32 bit unsigned integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Unsigned32(Offset offset) {
super(NativeType.UINT, offset);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
long value = getMemory().getInt(offset());
return value < 0 ? (long)((value & 0x7FFFFFFFL) + 0x80000000L) : value;
}
/**
* Sets the value for this field.
*
* @param value the 32 bit unsigned value to set.
*/
public final void set(long value) {
getMemory().putInt(offset(), (int) value);
}
public void set(java.lang.Number value) {
getMemory().putInt(offset(), value.intValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
}
/**
* A 64 bit signed integer field.
*/
public class Signed64 extends NumberField {
/**
* Creates a new 64 bit integer field.
*/
public Signed64() {
super(NativeType.SLONGLONG);
}
/**
* Creates a new 64 bit signed integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Signed64(Offset offset) {
super(NativeType.SLONGLONG, offset);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
return getMemory().getLongLong(offset());
}
/**
* Sets the value for this field.
*
* @param value the 64 bit value to set.
*/
public final void set(long value) {
getMemory().putLongLong(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putLongLong(offset(), value.longValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return java.lang.Long.toString(get());
}
}
/**
* A 64 bit unsigned integer field.
*/
public class Unsigned64 extends NumberField {
/**
* Creates a new 64 bit integer field.
*/
public Unsigned64() {
super(NativeType.ULONGLONG);
}
/**
* Creates a new 64 bit unsigned integer field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Unsigned64(Offset offset) {
super(NativeType.ULONGLONG, offset);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
return getMemory().getLongLong(offset());
}
/**
* Sets the value for this field.
*
* @param value the 64 bit value to set.
*/
public final void set(long value) {
getMemory().putLongLong(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putLongLong(offset(), value.longValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return java.lang.Long.toString(get());
}
}
/**
* A native long integer field.
*/
public class SignedLong extends NumberField {
/**
* Creates a new native long field.
*/
public SignedLong() {
super(NativeType.SLONG);
}
/**
* Creates a new signed native long field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public SignedLong(Offset offset) {
super(NativeType.SLONG, offset);
}
/**
* Gets the value for this field.
*
* @return a long.
*/
public final long get() {
return getMemory().getNativeLong(offset());
}
/**
* Sets the value for this field.
*
* @param value the 32/64 bit value to set.
*/
public final void set(long value) {
getMemory().putNativeLong(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putNativeLong(offset(), value.longValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return java.lang.Long.toString(get());
}
}
/**
* A native long integer field.
*/
public class UnsignedLong extends NumberField {
/**
* Creates a new native long field.
*/
public UnsignedLong() {
super(NativeType.ULONG);
}
/**
* Creates a new unsigned native long field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public UnsignedLong(Offset offset) {
super(NativeType.ULONG, offset);
}
/**
* Gets the value for this field.
*
* @return a int.
*/
public final long get() {
long value = getMemory().getNativeLong(offset());
final long mask = getRuntime().findType(NativeType.SLONG).size() == 32 ? 0xffffffffL : 0xffffffffffffffffL;
return value < 0
? (long) ((value & mask) + mask + 1)
: value;
}
/**
* Sets the value for this field.
*
* @param value the 32/64 bit value to set.
*/
public final void set(long value) {
getMemory().putNativeLong(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putNativeLong(offset(), value.longValue());
}
/**
* Returns a java int representation of this field.
*
* @return a java int value for this field.
*/
@Override
public final int intValue() {
return (int) get();
}
/**
* Returns a java long representation of this field.
*
* @return a java long value for this field.
*/
@Override
public final long longValue() {
return get();
}
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return java.lang.Long.toString(get());
}
}
public class Float extends NumberField {
public Float() {
super(NativeType.FLOAT);
}
/**
* Creates a new float field at a specific offset
*
* @param offset The offset within the memory area for this field.
*/
public Float(Offset offset) {
super(NativeType.FLOAT, offset);
}
public final float get() {
return getMemory().getFloat(offset());
}
public final void set(float value) {
getMemory().putFloat(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putFloat(offset(), value.floatValue());
}
@Override
public final int intValue() {
return (int) get();
}
@Override
public final double doubleValue() {
return get();
}
@Override
public final float floatValue() {
return get();
}
@Override
public final long longValue() {
return (long) get();
}
@Override
public final java.lang.String toString() {
return java.lang.String.valueOf(get());
}
}
public final class Double extends NumberField {
public Double() {
super(NativeType.DOUBLE);
}
public Double(Offset offset) {
super(NativeType.DOUBLE, offset);
}
public final double get() {
return getMemory().getDouble(offset());
}
public final void set(double value) {
getMemory().putDouble(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putDouble(offset(), value.doubleValue());
}
@Override
public final int intValue() {
return (int) get();
}
@Override
public final long longValue() {
return (long) get();
}
@Override
public final float floatValue() {
return (float) get();
}
@Override
public final double doubleValue() {
return get();
}
@Override
public final java.lang.String toString() {
return java.lang.String.valueOf(get());
}
}
/**
* Represents a native memory address.
*/
public class Address extends NumberField {
/**
* Creates a new Address field.
*/
public Address() {
super(NativeType.ADDRESS);
}
public Address(Offset offset) {
super(NativeType.ADDRESS, offset);
}
/**
* Reads an {@code Address} value from the struct.
*
* @return a {@link jnr.ffi.Address}.
*/
public final jnr.ffi.Address get() {
return jnr.ffi.Address.valueOf(getMemory().getAddress(offset()));
}
/**
* Puts a {@link jnr.ffi.Address} value into the native memory.
*
* @param value the value to write.
*/
public final void set(jnr.ffi.Address value) {
getMemory().putAddress(offset(), value != null ? value.nativeAddress() : 0);
}
public void set(java.lang.Number value) {
getMemory().putAddress(offset(), value.longValue());
}
/**
* Returns an integer representation of this address.
*
* @return an integer value for this address.
*/
@Override
public final int intValue() {
return get().intValue();
}
/**
* Returns an {@code long} representation of this address.
*
* @return an {@code long} value for this address.
*/
@Override
public final long longValue() {
return get().longValue();
}
/**
* Returns a string representation of this Address
.
*
* @return a string representation of this Address
.
*/
@Override
public final java.lang.String toString() {
return get().toString();
}
}
/**
* Represents a native memory address.
*/
public class Pointer extends NumberField {
/**
* Creates a new Address field.
*/
public Pointer() {
super(NativeType.ADDRESS);
}
public Pointer(Offset offset) {
super(NativeType.ADDRESS, offset);
}
/**
* Gets the {@link jnr.ffi.Pointer} value from the native memory.
*
* @return a {@link jnr.ffi.Pointer}.
*/
public final jnr.ffi.Pointer get() {
return getMemory().getPointer(offset());
}
/**
* Gets the size of a Pointer in bits
*
* @return the size of the Pointer
*/
public final int size() {
return getRuntime().findType(NativeType.ADDRESS).size() * 8;
}
/**
* Puts a {@link jnr.ffi.Address} value into the native memory.
*
* @param value the value to write.
*/
public final void set(jnr.ffi.Pointer value) {
getMemory().putPointer(offset(), value);
}
public void set(java.lang.Number value) {
getMemory().putAddress(offset(), value.longValue());
}
/**
* Returns an integer representation of this Pointer
.
*
* @return an integer value for this Pointer
.
*/
@Override
public final int intValue() {
return (int) getMemory().getAddress(offset());
}
/**
* Returns an {@code long} representation of this Pointer
.
*
* @return an {@code long} value for this Pointer
.
*/
@Override
public final long longValue() {
return getMemory().getAddress(offset());
}
/**
* Returns a string representation of this Pointer
.
*
* @return a string representation of this Pointer
.
*/
@Override
public final java.lang.String toString() {
return get().toString();
}
}
/**
* Base for all the Enum fields.
*
* @param the type of {@link java.lang.Enum}
*/
protected abstract class EnumField extends NumberField {
protected final Class enumClass;
/**
* Constructs a new Enum field.
*
* @param type the native type of the enum.
* @param enumClass the Enum class.
*/
public EnumField(NativeType type, Class enumClass) {
super(type);
this.enumClass = enumClass;
}
/**
* Gets a java Enum value representing the native integer value.
*
* @return a java Enum value.
*/
public abstract E get();
/**
* Returns a string representation of this field.
*
* @return a string representation of this field.
*/
@Override
public final java.lang.String toString() {
return get().toString();
}
}
/**
* An 8 bit enum field.
*
* @param the {@link java.lang.Enum} to translate to/from.
*/
public class Enum8> extends EnumField {
/**
* Creates a new 8 bit enum field.
*
* @param enumClass the class of the {@link java.lang.Enum}.
*/
public Enum8(Class enumClass) {
super(NativeType.SCHAR, enumClass);
}
/**
* Gets a java Enum value representing the native integer value.
*
* @return a java Enum value.
*/
public final E get() {
return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue()));
}
/**
* Sets the native integer value using a java Enum value.
*
* @param value the java Enum value.
*/
public final void set(E value) {
getMemory().putByte(offset(), (byte) EnumMapper.getInstance(enumClass).intValue(value));
}
public void set(java.lang.Number value) {
getMemory().putByte(offset(), value.byteValue());
}
/**
* Returns an integer representation of this enum field.
*
* @return an integer value for this enum field.
*/
@Override
public final int intValue() {
return getMemory().getByte(offset());
}
}
public class Enum16> extends EnumField {
public Enum16(Class enumClass) {
super(NativeType.SSHORT, enumClass);
}
public final E get() {
return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue()));
}
public final void set(E value) {
getMemory().putShort(offset(), (short) EnumMapper.getInstance(enumClass).intValue(value));
}
public void set(java.lang.Number value) {
getMemory().putShort(offset(), value.shortValue());
}
@Override
public final int intValue() {
return getMemory().getShort(offset());
}
}
public class Enum32> extends EnumField {
public Enum32(Class enumClass) {
super(NativeType.SINT, enumClass);
}
public final E get() {
return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue()));
}
public final void set(E value) {
getMemory().putInt(offset(), EnumMapper.getInstance(enumClass).intValue(value));
}
public void set(java.lang.Number value) {
getMemory().putInt(offset(), value.intValue());
}
@Override
public final int intValue() {
return getMemory().getInt(offset());
}
}
public class Enum64> extends EnumField {
public Enum64(Class enumClass) {
super(NativeType.SLONGLONG, enumClass);
}
public final E get() {
return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue()));
}
public final void set(E value) {
getMemory().putLongLong(offset(), EnumMapper.getInstance(enumClass).intValue(value));
}
public void set(java.lang.Number value) {
getMemory().putLongLong(offset(), value.longValue());
}
@Override
public final int intValue() {
return (int) longValue();
}
@Override
public final long longValue() {
return getMemory().getLongLong(offset());
}
}
public class EnumLong> extends EnumField {
public EnumLong(Class enumClass) {
super(NativeType.SLONG, enumClass);
}
public final E get() {
return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue()));
}
public final void set(E value) {
getMemory().putNativeLong(offset(), EnumMapper.getInstance(enumClass).intValue(value));
}
public void set(java.lang.Number value) {
getMemory().putNativeLong(offset(), value.longValue());
}
@Override
public final int intValue() {
return (int) longValue();
}
@Override
public final long longValue() {
return getMemory().getNativeLong(offset());
}
}
public class Enum> extends Enum32 {
public Enum(Class enumClass) {
super(enumClass);
}
}
abstract public class String extends AbstractMember {
protected final Charset charset;
protected final int length;
protected String(int size, int align, int length, Charset cs) {
super(size, align);
this.length = length;
this.charset = cs;
}
protected String(int size, int align, Offset offset, int length, Charset cs) {
super(size, align, offset);
this.length = length;
this.charset = cs;
}
public final int length() {
return length;
}
protected abstract jnr.ffi.Pointer getStringMemory();
public abstract java.lang.String get();
public abstract void set(java.lang.String value);
@Override
public final java.lang.String toString() {
return get();
}
}
public class UTFString extends String {
public UTFString(int length, Charset cs) {
super(length * 8, 8, length, cs); // FIXME: This won't work for non-ASCII
}
protected jnr.ffi.Pointer getStringMemory() {
return getMemory().slice(offset(), length());
}
public final java.lang.String get() {
return getStringMemory().getString(0, length, charset);
}
public final void set(java.lang.String value) {
getStringMemory().putString(0, value, length, charset);
}
}
public class UTF8String extends UTFString {
public UTF8String(int size) {
super(size, UTF8);
}
}
public class AsciiString extends UTFString {
public AsciiString(int size) {
super(size, ASCII);
}
}
public class UTFStringRef extends String {
private jnr.ffi.Pointer valueHolder;
public UTFStringRef(int length, Charset cs) {
super(getRuntime().findType(NativeType.ADDRESS).size() * 8, getRuntime().findType(NativeType.ADDRESS).alignment() * 8,
length, cs);
}
public UTFStringRef(Charset cs) {
this(Integer.MAX_VALUE, cs);
}
protected jnr.ffi.Pointer getStringMemory() {
return getMemory().getPointer(offset(), length());
}
public final java.lang.String get() {
jnr.ffi.Pointer ptr = getStringMemory();
return ptr != null ? ptr.getString(0, length, charset) : null;
}
public final void set(java.lang.String value) {
if (value != null) {
valueHolder = getRuntime().getMemoryManager().allocateDirect(length() * 4);
valueHolder.putString(0, value, length() * 4, charset);
getMemory().putPointer(offset(), valueHolder);
} else {
this.valueHolder = null;
getMemory().putAddress(offset(), 0);
}
}
}
public class UTF8StringRef extends UTFStringRef {
public UTF8StringRef(int size) {
super(size, UTF8);
}
public UTF8StringRef() {
super(Integer.MAX_VALUE, UTF8);
}
}
public class AsciiStringRef extends UTFStringRef {
public AsciiStringRef(int size) {
super(size, ASCII);
}
public AsciiStringRef() {
super(Integer.MAX_VALUE, ASCII);
}
}
/**
* Specialized padding fields for structs. Use this instead of arrays of other
* members for more efficient struct construction.
*/
protected final class Padding extends AbstractMember {
public Padding(Type type, int length) {
super(type.size() * 8 * length, type.alignment() * 8);
}
public Padding(NativeType type, int length) {
super(getRuntime().findType(type).size() * 8 * length, getRuntime().findType(type).alignment() * 8);
}
}
protected final class Function extends AbstractMember {
private final Class extends T> closureClass;
private T instance;
public Function(Class extends T> closureClass) {
super(NativeType.ADDRESS);
this.closureClass = closureClass;
}
public final void set(T value) {
getMemory().putPointer(offset(), getRuntime().getClosureManager().getClosurePointer(closureClass, instance = value));
}
}
protected final Function function(Class closureClass) {
return new Function(closureClass);
}
public final class int8_t extends IntegerAlias {
public int8_t() { super(TypeAlias.int8_t); }
public int8_t(Offset offset) { super(TypeAlias.int8_t, offset); }
}
public final class u_int8_t extends IntegerAlias {
public u_int8_t() { super(TypeAlias.u_int8_t); }
public u_int8_t(Offset offset) { super(TypeAlias.u_int8_t, offset); }
}
public final class int16_t extends IntegerAlias {
public int16_t() { super(TypeAlias.int16_t); }
public int16_t(Offset offset) { super(TypeAlias.int16_t, offset); }
}
public final class u_int16_t extends IntegerAlias {
public u_int16_t() { super(TypeAlias.u_int16_t); }
public u_int16_t(Offset offset) { super(TypeAlias.u_int16_t, offset); }
}
public final class int32_t extends IntegerAlias {
public int32_t() { super(TypeAlias.int32_t); }
public int32_t(Offset offset) { super(TypeAlias.int32_t, offset); }
}
public final class u_int32_t extends IntegerAlias {
public u_int32_t() { super(TypeAlias.u_int32_t); }
public u_int32_t(Offset offset) { super(TypeAlias.u_int32_t, offset); }
}
public final class int64_t extends IntegerAlias {
public int64_t() { super(TypeAlias.int64_t); }
public int64_t(Offset offset) { super(TypeAlias.int64_t, offset); }
}
public final class u_int64_t extends IntegerAlias {
public u_int64_t() { super(TypeAlias.u_int64_t); }
public u_int64_t(Offset offset) { super(TypeAlias.u_int64_t, offset); }
}
public final class intptr_t extends IntegerAlias {
public intptr_t() { super(TypeAlias.intptr_t); }
public intptr_t(Offset offset) { super(TypeAlias.intptr_t, offset); }
}
public final class uintptr_t extends IntegerAlias {
public uintptr_t() { super(TypeAlias.uintptr_t); }
public uintptr_t(Offset offset) { super(TypeAlias.uintptr_t, offset); }
}
public final class caddr_t extends IntegerAlias {
public caddr_t() { super(TypeAlias.caddr_t); }
public caddr_t(Offset offset) { super(TypeAlias.caddr_t, offset); }
}
public final class dev_t extends IntegerAlias {
public dev_t() { super(TypeAlias.dev_t); }
public dev_t(Offset offset) { super(TypeAlias.dev_t, offset); }
}
public final class blkcnt_t extends IntegerAlias {
public blkcnt_t() { super(TypeAlias.blkcnt_t); }
public blkcnt_t(Offset offset) { super(TypeAlias.blkcnt_t, offset); }
}
public final class blksize_t extends IntegerAlias {
public blksize_t() { super(TypeAlias.blksize_t); }
public blksize_t(Offset offset) { super(TypeAlias.blksize_t, offset); }
}
public final class gid_t extends IntegerAlias {
public gid_t() { super(TypeAlias.gid_t); }
public gid_t(Offset offset) { super(TypeAlias.gid_t, offset); }
}
public final class in_addr_t extends IntegerAlias {
public in_addr_t() { super(TypeAlias.in_addr_t); }
public in_addr_t(Offset offset) { super(TypeAlias.in_addr_t, offset); }
}
public final class in_port_t extends IntegerAlias {
public in_port_t() { super(TypeAlias.in_port_t); }
public in_port_t(Offset offset) { super(TypeAlias.in_port_t, offset); }
}
public final class ino_t extends IntegerAlias {
public ino_t() { super(TypeAlias.ino_t); }
public ino_t(Offset offset) { super(TypeAlias.ino_t, offset); }
}
public final class ino64_t extends IntegerAlias {
public ino64_t() { super(TypeAlias.ino64_t); }
public ino64_t(Offset offset) { super(TypeAlias.ino64_t, offset); }
}
public final class key_t extends IntegerAlias {
public key_t() { super(TypeAlias.key_t); }
public key_t(Offset offset) { super(TypeAlias.key_t, offset); }
}
public final class mode_t extends IntegerAlias {
public mode_t() { super(TypeAlias.mode_t); }
public mode_t(Offset offset) { super(TypeAlias.mode_t, offset); }
}
public final class nlink_t extends IntegerAlias {
public nlink_t() { super(TypeAlias.nlink_t); }
public nlink_t(Offset offset) { super(TypeAlias.nlink_t, offset); }
}
public final class id_t extends IntegerAlias {
public id_t() { super(TypeAlias.id_t); }
public id_t(Offset offset) { super(TypeAlias.id_t, offset); }
}
public final class pid_t extends IntegerAlias {
public pid_t() { super(TypeAlias.pid_t); }
public pid_t(Offset offset) { super(TypeAlias.pid_t, offset); }
}
public final class off_t extends IntegerAlias {
public off_t() { super(TypeAlias.off_t); }
public off_t(Offset offset) { super(TypeAlias.off_t, offset); }
}
public final class swblk_t extends IntegerAlias {
public swblk_t() { super(TypeAlias.swblk_t); }
public swblk_t(Offset offset) { super(TypeAlias.swblk_t, offset); }
}
public final class uid_t extends IntegerAlias {
public uid_t() { super(TypeAlias.uid_t); }
public uid_t(Offset offset) { super(TypeAlias.uid_t, offset); }
}
public final class clock_t extends IntegerAlias {
public clock_t() { super(TypeAlias.clock_t); }
public clock_t(Offset offset) { super(TypeAlias.clock_t, offset); }
}
public final class size_t extends IntegerAlias {
public size_t() { super(TypeAlias.size_t); }
public size_t(Offset offset) { super(TypeAlias.size_t, offset); }
}
public final class ssize_t extends IntegerAlias {
public ssize_t() { super(TypeAlias.ssize_t); }
public ssize_t(Offset offset) { super(TypeAlias.ssize_t, offset); }
}
public final class time_t extends IntegerAlias {
public time_t() { super(TypeAlias.time_t); }
public time_t(Offset offset) { super(TypeAlias.time_t, offset); }
}
public final class fsblkcnt_t extends IntegerAlias {
public fsblkcnt_t() { super(TypeAlias.fsblkcnt_t); }
public fsblkcnt_t(Offset offset) { super(TypeAlias.fsblkcnt_t, offset); }
}
public final class fsfilcnt_t extends IntegerAlias {
public fsfilcnt_t() { super(TypeAlias.fsfilcnt_t); }
public fsfilcnt_t(Offset offset) { super(TypeAlias.fsfilcnt_t, offset); }
}
public final class sa_family_t extends IntegerAlias {
public sa_family_t() { super(TypeAlias.sa_family_t); }
public sa_family_t(Offset offset) { super(TypeAlias.sa_family_t, offset); }
}
public final class socklen_t extends IntegerAlias {
public socklen_t() { super(TypeAlias.socklen_t); }
public socklen_t(Offset offset) { super(TypeAlias.socklen_t, offset); }
}
public final class rlim_t extends IntegerAlias {
public rlim_t() { super(TypeAlias.rlim_t); }
public rlim_t(Offset offset) { super(TypeAlias.rlim_t, offset); }
}
}