diff --git a/src/main/java/jnr/ffi/annotations/Direct.java b/src/main/java/jnr/ffi/annotations/Direct.java index 9d2ea8c27..5740546ec 100644 --- a/src/main/java/jnr/ffi/annotations/Direct.java +++ b/src/main/java/jnr/ffi/annotations/Direct.java @@ -19,13 +19,15 @@ package jnr.ffi.annotations; +import jnr.ffi.struct.Struct; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** - * Indicates that a {@link jnr.ffi.Struct}} parameter should be + * Indicates that a {@link Struct}} parameter should be * backed by a persistent native memory block. * *

Without the {@code @Direct} annotation, the native code will allocate a @@ -33,7 +35,7 @@ * the call. * *

By using {@code @Direct}, the native memory block is permanently associated - * with the {@link jnr.ffi.Struct} instance, and will remain allocated + * with the {@link Struct} instance, and will remain allocated * for as long as the {@code Struct} instance remains strongly referenced by java code. * */ diff --git a/src/main/java/jnr/ffi/annotations/In.java b/src/main/java/jnr/ffi/annotations/In.java index bc6f5c4d7..1a533f70d 100644 --- a/src/main/java/jnr/ffi/annotations/In.java +++ b/src/main/java/jnr/ffi/annotations/In.java @@ -18,6 +18,8 @@ package jnr.ffi.annotations; +import jnr.ffi.struct.Struct; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -27,7 +29,7 @@ * Indicates that the parameter is an IN parameter. * *

When a java object is passed to a native function as a pointer - * (for example {@link jnr.ffi.Pointer}, {@link jnr.ffi.Struct}, {@link java.nio.ByteBuffer}), + * (for example {@link jnr.ffi.Pointer}, {@link Struct}, {@link java.nio.ByteBuffer}), * then a temporary native memory block is allocated, the java data is copied to * the temporary memory and the address of the temporary memory is passed to the function. * After the function returns, the java data is automatically updated from the diff --git a/src/main/java/jnr/ffi/annotations/Out.java b/src/main/java/jnr/ffi/annotations/Out.java index cb843fca7..085777c2c 100644 --- a/src/main/java/jnr/ffi/annotations/Out.java +++ b/src/main/java/jnr/ffi/annotations/Out.java @@ -18,6 +18,8 @@ package jnr.ffi.annotations; +import jnr.ffi.struct.Struct; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -27,7 +29,7 @@ * Indicates that the parameter is an OUT parameter. * *

When a java object is passed to a native function as a pointer - * (for example {@link jnr.ffi.Pointer}, {@link jnr.ffi.Struct}, {@link java.nio.ByteBuffer}), + * (for example {@link jnr.ffi.Pointer}, {@link Struct}, {@link java.nio.ByteBuffer}), * then a temporary native memory block is allocated, the java data is copied to * the temporary memory and the address of the temporary memory is passed to the function. * After the function returns, the java data is automatically updated from the diff --git a/src/main/java/jnr/ffi/provider/converters/StructArrayParameterConverter.java b/src/main/java/jnr/ffi/provider/converters/StructArrayParameterConverter.java index d95cbd7ce..9f82568c5 100644 --- a/src/main/java/jnr/ffi/provider/converters/StructArrayParameterConverter.java +++ b/src/main/java/jnr/ffi/provider/converters/StructArrayParameterConverter.java @@ -19,8 +19,7 @@ package jnr.ffi.provider.converters; import jnr.ffi.Pointer; -import jnr.ffi.Struct; -import jnr.ffi.annotations.LongLong; +import jnr.ffi.struct.Struct; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.DelegatingMemoryIO; diff --git a/src/main/java/jnr/ffi/provider/converters/StructByReferenceFromNativeConverter.java b/src/main/java/jnr/ffi/provider/converters/StructByReferenceFromNativeConverter.java index 59b5d487a..16b3acdd1 100644 --- a/src/main/java/jnr/ffi/provider/converters/StructByReferenceFromNativeConverter.java +++ b/src/main/java/jnr/ffi/provider/converters/StructByReferenceFromNativeConverter.java @@ -19,7 +19,7 @@ package jnr.ffi.provider.converters; import jnr.ffi.Pointer; -import jnr.ffi.Struct; +import jnr.ffi.struct.Struct; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; @@ -28,7 +28,7 @@ /** - * Converts a native pointer result into a {@link jnr.ffi.Struct} + * Converts a native pointer result into a {@link Struct} */ public class StructByReferenceFromNativeConverter implements FromNativeConverter { private final Constructor constructor; diff --git a/src/main/java/jnr/ffi/provider/converters/StructByReferenceToNativeConverter.java b/src/main/java/jnr/ffi/provider/converters/StructByReferenceToNativeConverter.java index 7d7baa992..c06dfbc3e 100644 --- a/src/main/java/jnr/ffi/provider/converters/StructByReferenceToNativeConverter.java +++ b/src/main/java/jnr/ffi/provider/converters/StructByReferenceToNativeConverter.java @@ -19,7 +19,7 @@ package jnr.ffi.provider.converters; import jnr.ffi.Pointer; -import jnr.ffi.Struct; +import jnr.ffi.struct.Struct; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; diff --git a/src/main/java/jnr/ffi/provider/jffi/AsmStructByReferenceFromNativeConverter.java b/src/main/java/jnr/ffi/provider/jffi/AsmStructByReferenceFromNativeConverter.java index 6970a5cf8..d5a2ed284 100644 --- a/src/main/java/jnr/ffi/provider/jffi/AsmStructByReferenceFromNativeConverter.java +++ b/src/main/java/jnr/ffi/provider/jffi/AsmStructByReferenceFromNativeConverter.java @@ -20,7 +20,7 @@ import jnr.ffi.Pointer; import jnr.ffi.Runtime; -import jnr.ffi.Struct; +import jnr.ffi.struct.Struct; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import org.objectweb.asm.ClassReader; diff --git a/src/main/java/jnr/ffi/provider/jffi/ClosureTypeMapper.java b/src/main/java/jnr/ffi/provider/jffi/ClosureTypeMapper.java index b647df006..891953312 100644 --- a/src/main/java/jnr/ffi/provider/jffi/ClosureTypeMapper.java +++ b/src/main/java/jnr/ffi/provider/jffi/ClosureTypeMapper.java @@ -18,12 +18,11 @@ package jnr.ffi.provider.jffi; -import jnr.ffi.Struct; +import jnr.ffi.struct.Struct; import jnr.ffi.mapper.*; import jnr.ffi.mapper.FromNativeType; import jnr.ffi.mapper.ToNativeType; import jnr.ffi.provider.converters.EnumConverter; -import jnr.ffi.provider.ParameterFlags; import jnr.ffi.provider.converters.StringResultConverter; import jnr.ffi.provider.converters.StructByReferenceToNativeConverter; diff --git a/src/main/java/jnr/ffi/provider/jffi/InvokerTypeMapper.java b/src/main/java/jnr/ffi/provider/jffi/InvokerTypeMapper.java index 42c8cda0c..5cc5cbfb8 100644 --- a/src/main/java/jnr/ffi/provider/jffi/InvokerTypeMapper.java +++ b/src/main/java/jnr/ffi/provider/jffi/InvokerTypeMapper.java @@ -20,7 +20,7 @@ import jnr.ffi.NativeLong; import jnr.ffi.Pointer; -import jnr.ffi.Struct; +import jnr.ffi.struct.Struct; import jnr.ffi.annotations.Delegate; import jnr.ffi.byref.ByReference; import jnr.ffi.mapper.*; diff --git a/src/main/java/jnr/ffi/provider/jffi/StructByReferenceResultConverterFactory.java b/src/main/java/jnr/ffi/provider/jffi/StructByReferenceResultConverterFactory.java index aef263e14..9ddf4f2d9 100644 --- a/src/main/java/jnr/ffi/provider/jffi/StructByReferenceResultConverterFactory.java +++ b/src/main/java/jnr/ffi/provider/jffi/StructByReferenceResultConverterFactory.java @@ -22,6 +22,7 @@ import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import jnr.ffi.provider.converters.StructByReferenceFromNativeConverter; +import jnr.ffi.struct.Struct; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; diff --git a/src/main/java/jnr/ffi/struct/AsciiString.java b/src/main/java/jnr/ffi/struct/AsciiString.java new file mode 100644 index 000000000..23aa3e41d --- /dev/null +++ b/src/main/java/jnr/ffi/struct/AsciiString.java @@ -0,0 +1,10 @@ +package jnr.ffi.struct; + +public class AsciiString extends UTFString { + private Struct struct; + + public AsciiString(Struct struct, int size) { + super(struct, size, Struct.ASCII); + this.struct = struct; + } +} diff --git a/src/main/java/jnr/ffi/struct/Field.java b/src/main/java/jnr/ffi/struct/Field.java new file mode 100644 index 000000000..51f7de36a --- /dev/null +++ b/src/main/java/jnr/ffi/struct/Field.java @@ -0,0 +1,68 @@ +package jnr.ffi.struct; + +import jnr.ffi.NativeType; +import jnr.ffi.Runtime; +import jnr.ffi.Type; +import jnr.ffi.TypeAlias; + +/** + * Structure field + */ +public abstract class Field { + + private Struct.Info info; + private Offset offset; + + protected Field(Struct struct, int size, int align, Offset offset) { + registerInStructure(struct, size, align, offset); + } + + protected Field(Struct struct, int size, int align) { + this(struct, size, align, null); + } + + protected Field(Struct struct, NativeType nativeType) { + this(struct, nativeType, null); + } + + protected Field(Struct struct, NativeType nativeType, Offset offset) { + final Type type = struct.getRuntime().findType(nativeType); + registerInStructure(struct, type, offset); + } + + protected Field(Struct struct, TypeAlias typeAlias) { + this(struct, typeAlias, null); + } + + protected Field(Struct struct, TypeAlias typeAlias, Offset offset) { + Type type = struct.getRuntime().findType(typeAlias); + registerInStructure(struct, type, offset); + } + + private void registerInStructure(Struct struct, Type type, Offset offset) { + registerInStructure(struct, type.size() * 8, type.alignment() * 8, offset); + } + + public final jnr.ffi.Pointer getMemory() { + return info.getMemory(); + } + + public final Runtime getRuntime() { + return info.getRuntime(); + } + + protected long offset() { + return offset.intValue() + info.getOffset(); + } + + private void registerInStructure(Struct struct, int size, int alignment, Offset offset) { + info = struct.__info; + if (offset == null) { + int offsetAfterAllocation = struct.__info.addField(size, alignment); + this.offset = new Offset(offsetAfterAllocation); + } else { + struct.__info.addField(size, alignment, offset); + } + + } +} diff --git a/src/main/java/jnr/ffi/struct/Offset.java b/src/main/java/jnr/ffi/struct/Offset.java new file mode 100644 index 000000000..be4579a64 --- /dev/null +++ b/src/main/java/jnr/ffi/struct/Offset.java @@ -0,0 +1,24 @@ +package jnr.ffi.struct; + +public final class Offset extends 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; + } +} diff --git a/src/main/java/jnr/ffi/struct/StringField.java b/src/main/java/jnr/ffi/struct/StringField.java new file mode 100644 index 000000000..4e2586de1 --- /dev/null +++ b/src/main/java/jnr/ffi/struct/StringField.java @@ -0,0 +1,38 @@ +package jnr.ffi.struct; + +import jnr.ffi.NativeType; + +import java.nio.charset.Charset; + +abstract public class StringField extends Field { + protected final Charset charset; + protected final int length; + + protected StringField(Struct struct, NativeType nativeType, int length, Charset cs) { + super(struct, nativeType); + this.length = length; + this.charset = cs; + } + protected StringField(Struct struct, int size, int align, int length, Charset cs) { + super(struct, size, align); + this.length = length; + this.charset = cs; + } + protected StringField(Struct struct, int size, int align, Offset offset, int length, Charset cs) { + super(struct, 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(); + } +} diff --git a/src/main/java/jnr/ffi/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java similarity index 92% rename from src/main/java/jnr/ffi/Struct.java rename to src/main/java/jnr/ffi/struct/Struct.java index f235472cb..7c416899e 100755 --- a/src/main/java/jnr/ffi/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -25,8 +25,10 @@ * freely granted, provided that this notice is preserved. */ -package jnr.ffi; +package jnr.ffi.struct; +import jnr.ffi.*; +import jnr.ffi.Runtime; import jnr.ffi.provider.ParameterFlags; import jnr.ffi.provider.jffi.ArrayMemoryIO; import jnr.ffi.util.EnumMapper; @@ -73,6 +75,10 @@ public final jnr.ffi.Pointer getMemory() { return getMemory(ParameterFlags.TRANSIENT); } + public final Runtime getRuntime() { + return runtime; + } + final boolean isDirect() { return (enclosing != null && enclosing.__info.isDirect()) || (memory != null && memory.isDirect()); } @@ -144,7 +150,7 @@ protected Struct(Runtime runtime, final boolean isUnion) { } public final Runtime getRuntime() { - return __info.runtime; + return __info.getRuntime(); } /** @@ -233,29 +239,6 @@ public java.lang.String toString() { 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; - } - } - public static final class Alignment extends Number { private final int alignment; @@ -284,32 +267,6 @@ public double doubleValue() { } } - /** - * 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 */ @@ -325,14 +282,14 @@ protected final void arrayEnd() { } /** - * Creates an array of Member instances. + * Creates an array of Field instances. * - * @param The type of the Member subclass to create. + * @param The type of the Field 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) { + protected T[] array(T[] array) { arrayBegin(); try { Class arrayClass = array.getClass().getComponentType(); @@ -673,10 +630,10 @@ protected final Pointer[] array(Pointer[] array) { * @param stringLength length of each string in array * @return the array that was passed in */ - protected UTF8String[] array(UTF8String[] array, int stringLength) { + protected jnr.ffi.struct.UTF8String[] array(jnr.ffi.struct.UTF8String[] array, int stringLength) { arrayBegin(); for (int i = 0; i < array.length; i++) { - array[i] = new UTF8String(stringLength); + array[i] = new jnr.ffi.struct.UTF8String(this, stringLength); } arrayEnd(); return array; @@ -691,62 +648,16 @@ protected final T inner(T struct) { 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.getOffset(); - } - } - /** * Base class for Boolean fields */ - protected abstract class AbstractBoolean extends AbstractMember { + protected abstract class AbstractBoolean extends Field { protected AbstractBoolean(NativeType type) { - super(type); + super(Struct.this, type); } protected AbstractBoolean(NativeType type, Offset offset) { - super(type, offset); + super(Struct.this, type, offset); } /** @@ -861,53 +772,30 @@ public LONG(Offset offset) { /** * Base class for all Number structure fields. */ - public abstract class NumberField extends Member { + public abstract class NumberField extends Field { /** * 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) { + super(Struct.this, type); Type t = this.type = getRuntime().findType(type); - this.offset = __info.addField(t.size() * 8, t.alignment() * 8); } protected NumberField(NativeType type, Offset offset) { + super(Struct.this, type, offset); Type t = this.type = getRuntime().findType(type); - this.offset = __info.addField(t.size() * 8, t.alignment() * 8, offset); } protected NumberField(TypeAlias type) { + super(Struct.this, type); Type t = this.type = getRuntime().findType(type); - this.offset = __info.addField(t.size() * 8, t.alignment() * 8); } protected NumberField(TypeAlias type, Offset offset) { + super(Struct.this, type, 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.getOffset(); } /** @@ -2280,70 +2168,41 @@ public Enum(Class 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 { + /** + * Use {@link jnr.ffi.struct.UTFString} instead + */ + @Deprecated + public class UTFString extends jnr.ffi.struct.UTFString { 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); + super(Struct.this, length, cs); } } - public class UTF8String extends UTFString { + /** + * Use {@link jnr.ffi.struct.UTF8String} instead + */ + @Deprecated + public class UTF8String extends jnr.ffi.struct.UTF8String { public UTF8String(int size) { - super(size, UTF8); + super(Struct.this, size); } } - public class AsciiString extends UTFString { + /** + * Use {@link jnr.ffi.struct.AsciiString} instead + */ + @Deprecated + public class AsciiString extends jnr.ffi.struct.AsciiString { public AsciiString(int size) { - super(size, ASCII); + super(Struct.this, size); } } - public class UTFStringRef extends String { + public class UTFStringRef extends StringField { 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); + super(Struct.this, NativeType.ADDRESS, length, cs); } public UTFStringRef(Charset cs) { @@ -2394,22 +2253,22 @@ public AsciiStringRef() { * Specialized padding fields for structs. Use this instead of arrays of other * members for more efficient struct construction. */ - protected final class Padding extends AbstractMember { + protected final class Padding extends Field { public Padding(Type type, int length) { - super(type.size() * 8 * length, type.alignment() * 8); + super(Struct.this, 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); + this(Struct.this.getRuntime().findType(type), length); } } - public final class Function extends AbstractMember { + public final class Function extends Field { private final Class closureClass; private T instance; public Function(Class closureClass) { - super(NativeType.ADDRESS); + super(Struct.this, NativeType.ADDRESS); this.closureClass = closureClass; } diff --git a/src/main/java/jnr/ffi/struct/UTF8String.java b/src/main/java/jnr/ffi/struct/UTF8String.java new file mode 100644 index 000000000..e9d32d56f --- /dev/null +++ b/src/main/java/jnr/ffi/struct/UTF8String.java @@ -0,0 +1,10 @@ +package jnr.ffi.struct; + +public class UTF8String extends UTFString { + private Struct struct; + + public UTF8String(Struct struct, int size) { + super(struct, size, Struct.UTF8); + this.struct = struct; + } +} diff --git a/src/main/java/jnr/ffi/struct/UTFString.java b/src/main/java/jnr/ffi/struct/UTFString.java new file mode 100644 index 000000000..8f128e896 --- /dev/null +++ b/src/main/java/jnr/ffi/struct/UTFString.java @@ -0,0 +1,21 @@ +package jnr.ffi.struct; + +import java.nio.charset.Charset; + +public class UTFString extends StringField { + public UTFString( Struct struct, int length, Charset cs) { + super(struct,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); + } +} diff --git a/src/main/java/jnr/ffi/Union.java b/src/main/java/jnr/ffi/struct/Union.java similarity index 95% rename from src/main/java/jnr/ffi/Union.java rename to src/main/java/jnr/ffi/struct/Union.java index 693818d3c..03261a84c 100644 --- a/src/main/java/jnr/ffi/Union.java +++ b/src/main/java/jnr/ffi/struct/Union.java @@ -25,7 +25,9 @@ * freely granted, provided that this notice is preserved. */ -package jnr.ffi; +package jnr.ffi.struct; + +import jnr.ffi.Runtime; /** * Represents a C union diff --git a/src/test/java/jnr/ffi/DelegateTest.java b/src/test/java/jnr/ffi/DelegateTest.java index 3575a1036..c34577828 100644 --- a/src/test/java/jnr/ffi/DelegateTest.java +++ b/src/test/java/jnr/ffi/DelegateTest.java @@ -20,6 +20,7 @@ import jnr.ffi.annotations.Delegate; import jnr.ffi.annotations.LongLong; +import jnr.ffi.struct.Struct; import jnr.ffi.types.u_int32_t; import org.junit.*; diff --git a/src/test/java/jnr/ffi/PointerTest.java b/src/test/java/jnr/ffi/PointerTest.java index eb98658b5..5866fc85c 100644 --- a/src/test/java/jnr/ffi/PointerTest.java +++ b/src/test/java/jnr/ffi/PointerTest.java @@ -19,6 +19,7 @@ package jnr.ffi; import jnr.ffi.annotations.*; +import jnr.ffi.struct.Struct; import jnr.ffi.types.int32_t; import jnr.ffi.types.int8_t; import jnr.ffi.types.size_t; diff --git a/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java b/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java index ea5b8042f..de78e2c16 100644 --- a/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java +++ b/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java @@ -18,8 +18,6 @@ package jnr.ffi.struct; -import jnr.ffi.Library; -import jnr.ffi.Struct; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import jnr.ffi.annotations.Pinned; @@ -41,7 +39,7 @@ public class AsciiStringFieldTest { public AsciiStringFieldTest() { } public class StringFieldStruct extends Struct { - public final String string = new AsciiString(32); + public final StringField string = new jnr.ffi.struct.AsciiString(this, 32); public StringFieldStruct() { super(runtime); diff --git a/src/test/java/jnr/ffi/struct/FieldTest.java b/src/test/java/jnr/ffi/struct/FieldTest.java new file mode 100644 index 000000000..e21e4afe0 --- /dev/null +++ b/src/test/java/jnr/ffi/struct/FieldTest.java @@ -0,0 +1,71 @@ +package jnr.ffi.struct; + +import jnr.ffi.NativeType; +import jnr.ffi.Runtime; +import jnr.ffi.TstUtil; +import org.junit.BeforeClass; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class FieldTest { + + static class CustomChar extends Field { + + CustomChar(Struct struct) { + super(struct, NativeType.SCHAR); + } + + public final byte get() { + return getMemory().getByte(offset()); + } + + public final void set(byte value) { + getMemory().putByte(offset(), value); + } + } + + static class CustomStruct extends Struct { + + CustomStruct(Runtime runtime) { + super(runtime); + } + + CustomChar customChar = new CustomChar(this); + CharStruct innerStruct = inner(new CharStruct(getRuntime())); + } + + static class CharStruct extends Struct { + + CharStruct(Runtime runtime) { + super(runtime); + } + + CustomChar customChar = new CustomChar(this); + } + + public static interface TestLib { + byte struct_field_Signed8(CustomStruct s); + byte struct_field_Signed8(CharStruct s); + } + + static TestLib testlib; + static Runtime runtime; + + @BeforeClass + public static void setUpClass() throws Exception { + testlib = TstUtil.loadTestLib(TestLib.class); + runtime = Runtime.getRuntime(testlib); + } + + @Test + public void byteField() { + final byte MAGIC = (byte) 0xbe; + CharStruct s = new CharStruct(runtime); + s.customChar.set(MAGIC); + + assertEquals("byte field not set", MAGIC, testlib.struct_field_Signed8(s)); + s.customChar.set((byte) 0); + assertEquals("byte field not cleared", (byte) 0, testlib.struct_field_Signed8(s)); + } +} \ No newline at end of file diff --git a/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java b/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java index 9aecd7a8a..91d5bcb11 100644 --- a/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java +++ b/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java @@ -18,9 +18,7 @@ package jnr.ffi.struct; -import jnr.ffi.Struct; import jnr.ffi.TstUtil; -import jnr.ffi.Library; import jnr.ffi.Runtime; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; @@ -42,7 +40,7 @@ public UTF8StringFieldTest() { } public static class StringFieldStruct extends Struct { - public final UTF8String string = new UTF8String(32); + public final jnr.ffi.struct.UTF8String string = new jnr.ffi.struct.UTF8String(this, 32); public StringFieldStruct() { super(runtime); @@ -89,7 +87,7 @@ public void tearDown() { public static final class SockaddrUnix extends Struct { private final Signed8 sun_len = new Signed8(); private final Signed8 sun_family = new Signed8(); - private final UTF8String sun_path = new UTF8String(100); + private final jnr.ffi.struct.UTF8String sun_path = new jnr.ffi.struct.UTF8String(this, 100); public SockaddrUnix() { super(runtime); diff --git a/src/test/java/jnr/ffi/struct/UnionTest.java b/src/test/java/jnr/ffi/struct/UnionTest.java index f26b364d1..d4a95e635 100644 --- a/src/test/java/jnr/ffi/struct/UnionTest.java +++ b/src/test/java/jnr/ffi/struct/UnionTest.java @@ -21,9 +21,7 @@ import java.nio.ByteOrder; import jnr.ffi.Runtime; -import jnr.ffi.Struct; import jnr.ffi.TstUtil; -import jnr.ffi.Union; import org.junit.After; import org.junit.AfterClass; import org.junit.Before;