From 1b3766e8a9e67f3309414293577de854d9c22c5c Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 18:58:12 +0300 Subject: [PATCH 01/11] Move Struct and Union classes in jnr.ffi.struct package --- src/main/java/jnr/ffi/annotations/Direct.java | 6 ++++-- src/main/java/jnr/ffi/annotations/In.java | 4 +++- src/main/java/jnr/ffi/annotations/Out.java | 4 +++- .../provider/converters/StructArrayParameterConverter.java | 3 +-- .../converters/StructByReferenceFromNativeConverter.java | 4 ++-- .../converters/StructByReferenceToNativeConverter.java | 2 +- .../jffi/AsmStructByReferenceFromNativeConverter.java | 2 +- src/main/java/jnr/ffi/provider/jffi/ClosureTypeMapper.java | 3 +-- src/main/java/jnr/ffi/provider/jffi/InvokerTypeMapper.java | 2 +- .../jffi/StructByReferenceResultConverterFactory.java | 1 + src/main/java/jnr/ffi/{ => struct}/Struct.java | 4 +++- src/main/java/jnr/ffi/{ => struct}/Union.java | 4 +++- src/test/java/jnr/ffi/DelegateTest.java | 1 + src/test/java/jnr/ffi/PointerTest.java | 1 + src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java | 2 -- src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java | 2 -- src/test/java/jnr/ffi/struct/UnionTest.java | 2 -- 17 files changed, 26 insertions(+), 21 deletions(-) rename src/main/java/jnr/ffi/{ => struct}/Struct.java (99%) rename src/main/java/jnr/ffi/{ => struct}/Union.java (95%) 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.java b/src/main/java/jnr/ffi/struct/Struct.java similarity index 99% rename from src/main/java/jnr/ffi/Struct.java rename to src/main/java/jnr/ffi/struct/Struct.java index f235472cb..1f85fa9ea 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; 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..5f45f00a6 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; diff --git a/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java b/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java index 9aecd7a8a..a48288098 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; 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; From bfb7a3ba2cabaa7c3088a24d4e9b687bd88b8c96 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 19:40:01 +0300 Subject: [PATCH 02/11] Delete struct() method from Struct$Member --- src/main/java/jnr/ffi/struct/Struct.java | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/main/java/jnr/ffi/struct/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index 1f85fa9ea..ca617f20f 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -290,12 +290,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} @@ -722,15 +716,6 @@ 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. */ @@ -896,15 +881,6 @@ public final jnr.ffi.Pointer 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. */ From 11fa60d2cae28eee74c2076044de1ac7e00c94e2 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 21:04:18 +0300 Subject: [PATCH 03/11] Add struct Field class --- src/main/java/jnr/ffi/struct/Field.java | 49 ++++++++++++++ src/main/java/jnr/ffi/struct/Offset.java | 24 +++++++ src/main/java/jnr/ffi/struct/Struct.java | 23 ------- src/test/java/jnr/ffi/struct/FieldTest.java | 71 +++++++++++++++++++++ 4 files changed, 144 insertions(+), 23 deletions(-) create mode 100644 src/main/java/jnr/ffi/struct/Field.java create mode 100644 src/main/java/jnr/ffi/struct/Offset.java create mode 100644 src/test/java/jnr/ffi/struct/FieldTest.java 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..06b392a90 --- /dev/null +++ b/src/main/java/jnr/ffi/struct/Field.java @@ -0,0 +1,49 @@ +package jnr.ffi.struct; + +import jnr.ffi.NativeType; +import jnr.ffi.Type; + +/** + * 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 type) { + this(struct, type, null); + } + + protected Field(Struct struct, NativeType type, Offset offset) { + final Type t = struct.getRuntime().findType(type); + registerInStructure(struct, t.size() * 8, t.alignment() * 8, offset); + } + + protected jnr.ffi.Pointer getMemory() { + return info.getMemory(); + } + + protected int offset() { + return offset.intValue(); + } + + 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/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index ca617f20f..3e0575aa9 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -235,29 +235,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; 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 From ac4079d34953afa778313fe8ecab985084714d82 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 21:12:26 +0300 Subject: [PATCH 04/11] Inherit AbstractMember from Field class --- src/main/java/jnr/ffi/struct/Field.java | 6 +++--- src/main/java/jnr/ffi/struct/Struct.java | 23 +++++++---------------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/src/main/java/jnr/ffi/struct/Field.java b/src/main/java/jnr/ffi/struct/Field.java index 06b392a90..a7a6b2701 100644 --- a/src/main/java/jnr/ffi/struct/Field.java +++ b/src/main/java/jnr/ffi/struct/Field.java @@ -28,12 +28,12 @@ protected Field(Struct struct, NativeType type, Offset offset) { registerInStructure(struct, t.size() * 8, t.alignment() * 8, offset); } - protected jnr.ffi.Pointer getMemory() { + public final jnr.ffi.Pointer getMemory() { return info.getMemory(); } - protected int offset() { - return offset.intValue(); + protected long offset() { + return offset.intValue() + info.getOffset(); } private void registerInStructure(Struct struct, int size, int alignment, Offset offset) { diff --git a/src/main/java/jnr/ffi/struct/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index 3e0575aa9..ae1e9b0a3 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -667,38 +667,29 @@ protected final T inner(T struct) { /** * Base implementation of Member */ - protected abstract class AbstractMember extends Member { - private final int offset; + protected abstract class AbstractMember extends Field { protected AbstractMember(int size) { this(size, size); } + protected AbstractMember(int size, int align, Offset offset) { - this.offset = __info.addField(size, align, offset); + super(Struct.this, size, align, offset); } + protected AbstractMember(int size, int align) { - this.offset = __info.addField(size, align); + super(Struct.this, size, align); } protected AbstractMember(NativeType type) { - final Type t = getRuntime().findType(type); - this.offset = __info.addField(t.size() * 8, t.alignment() * 8); + super(Struct.this, type); } protected AbstractMember(NativeType type, Offset offset) { - final Type t = getRuntime().findType(type); - this.offset = __info.addField(t.size() * 8, t.alignment() * 8, offset); + super(Struct.this, type, offset); } - - public final jnr.ffi.Pointer getMemory() { - return __info.getMemory(); - } - /** * Gets the offset within the structure for this field. */ - public final long offset() { - return offset + __info.getOffset(); - } } /** From 9c193e2b92ac16ce77c1078833dc6e516dd0a1f2 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 21:22:58 +0300 Subject: [PATCH 05/11] Inherit NumberField from Field class --- src/main/java/jnr/ffi/struct/Field.java | 24 +++++++++++++++++++----- src/main/java/jnr/ffi/struct/Struct.java | 24 +++++------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/main/java/jnr/ffi/struct/Field.java b/src/main/java/jnr/ffi/struct/Field.java index a7a6b2701..7fbb15490 100644 --- a/src/main/java/jnr/ffi/struct/Field.java +++ b/src/main/java/jnr/ffi/struct/Field.java @@ -2,6 +2,7 @@ import jnr.ffi.NativeType; import jnr.ffi.Type; +import jnr.ffi.TypeAlias; /** * Structure field @@ -19,13 +20,26 @@ protected Field(Struct struct, int size, int align) { this(struct, size, align, null); } - protected Field(Struct struct, NativeType type) { - this(struct, type, null); + protected Field(Struct struct, NativeType nativeType) { + this(struct, nativeType, null); } - protected Field(Struct struct, NativeType type, Offset offset) { - final Type t = struct.getRuntime().findType(type); - registerInStructure(struct, t.size() * 8, t.alignment() * 8, offset); + 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() { diff --git a/src/main/java/jnr/ffi/struct/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index ae1e9b0a3..2e67f29e5 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -816,44 +816,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 offset within the structure for this field. - */ - public final long offset() { - return offset + __info.getOffset(); } /** From 57ad5521646ba8eccf658130ff5418472d592e3c Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 21:25:43 +0300 Subject: [PATCH 06/11] Delete Member class --- src/main/java/jnr/ffi/struct/Struct.java | 28 ++++-------------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/main/java/jnr/ffi/struct/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index 2e67f29e5..bb91880aa 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -263,26 +263,6 @@ public double doubleValue() { } } - /** - * Interface all Struct members must implement. - */ - protected abstract class Member { - - /** - * 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 */ @@ -298,14 +278,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(); @@ -665,7 +645,7 @@ protected final T inner(T struct) { } /** - * Base implementation of Member + * Base implementation of Field */ protected abstract class AbstractMember extends Field { protected AbstractMember(int size) { From de8dc726959c8452777bd0d157e963ea24157198 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 21:35:10 +0300 Subject: [PATCH 07/11] Add method getRuntime() to Field class --- src/main/java/jnr/ffi/struct/Field.java | 5 +++++ src/main/java/jnr/ffi/struct/Struct.java | 16 ++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/main/java/jnr/ffi/struct/Field.java b/src/main/java/jnr/ffi/struct/Field.java index 7fbb15490..51f7de36a 100644 --- a/src/main/java/jnr/ffi/struct/Field.java +++ b/src/main/java/jnr/ffi/struct/Field.java @@ -1,6 +1,7 @@ package jnr.ffi.struct; import jnr.ffi.NativeType; +import jnr.ffi.Runtime; import jnr.ffi.Type; import jnr.ffi.TypeAlias; @@ -46,6 +47,10 @@ public final jnr.ffi.Pointer getMemory() { return info.getMemory(); } + public final Runtime getRuntime() { + return info.getRuntime(); + } + protected long offset() { return offset.intValue() + info.getOffset(); } diff --git a/src/main/java/jnr/ffi/struct/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index bb91880aa..b0a2e4061 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -75,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()); } @@ -146,7 +150,7 @@ protected Struct(Runtime runtime, final boolean isUnion) { } public final Runtime getRuntime() { - return __info.runtime; + return __info.getRuntime(); } /** @@ -2196,6 +2200,11 @@ abstract public class String extends AbstractMember { protected final Charset charset; protected final int length; + protected String(NativeType nativeType, int length, Charset cs) { + super(nativeType); + this.length = length; + this.charset = cs; + } protected String(int size, int align, int length, Charset cs) { super(size, align); this.length = length; @@ -2254,8 +2263,7 @@ 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); + super(NativeType.ADDRESS, length, cs); } public UTFStringRef(Charset cs) { @@ -2312,7 +2320,7 @@ public Padding(Type type, int length) { } public Padding(NativeType type, int length) { - super(getRuntime().findType(type).size() * 8 * length, getRuntime().findType(type).alignment() * 8); + super(Struct.this.getRuntime().findType(type).size() * 8 * length, Struct.this.getRuntime().findType(type).alignment() * 8); } } From 85787336b1d70a512df3f260b2d31badcfae4232 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 21:37:41 +0300 Subject: [PATCH 08/11] Change Padding constructor --- src/main/java/jnr/ffi/struct/Struct.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/jnr/ffi/struct/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index b0a2e4061..8d93ca54d 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -2320,7 +2320,7 @@ public Padding(Type type, int length) { } public Padding(NativeType type, int length) { - super(Struct.this.getRuntime().findType(type).size() * 8 * length, Struct.this.getRuntime().findType(type).alignment() * 8); + this(Struct.this.getRuntime().findType(type), length); } } From 1715a9d29283c6c07ec34b766cdda668c17a12f7 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 22:01:26 +0300 Subject: [PATCH 09/11] Replace AbstractMember with Field --- src/main/java/jnr/ffi/struct/Struct.java | 50 ++++++------------------ 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/src/main/java/jnr/ffi/struct/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index 8d93ca54d..4c1f15930 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -648,44 +648,16 @@ protected final T inner(T struct) { return struct; } - /** - * Base implementation of Field - */ - protected abstract class AbstractMember extends Field { - protected AbstractMember(int size) { - this(size, size); - } - - protected AbstractMember(int size, int align, Offset offset) { - super(Struct.this, size, align, offset); - } - - protected AbstractMember(int size, int align) { - super(Struct.this, size, align); - } - - protected AbstractMember(NativeType type) { - super(Struct.this, type); - } - - protected AbstractMember(NativeType type, Offset offset) { - super(Struct.this, type, offset); - } - /** - * Gets the offset within the structure for this field. - */ - } - /** * 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); } /** @@ -2196,22 +2168,22 @@ public Enum(Class enumClass) { } } - abstract public class String extends AbstractMember { + abstract public class String extends Field { protected final Charset charset; protected final int length; protected String(NativeType nativeType, int length, Charset cs) { - super(nativeType); + super(Struct.this, nativeType); this.length = length; this.charset = cs; } protected String(int size, int align, int length, Charset cs) { - super(size, align); + super(Struct.this, size, align); this.length = length; this.charset = cs; } protected String(int size, int align, Offset offset, int length, Charset cs) { - super(size, align, offset); + super(Struct.this, size, align, offset); this.length = length; this.charset = cs; } @@ -2314,9 +2286,9 @@ 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) { @@ -2324,12 +2296,12 @@ public Padding(NativeType type, int 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; } From 02d6f62efb8c32c1bc9a84f36c4bcc363fd1d856 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 22:08:32 +0300 Subject: [PATCH 10/11] Move String field to package level --- src/main/java/jnr/ffi/struct/StringField.java | 38 +++++++++++++++++ src/main/java/jnr/ffi/struct/Struct.java | 41 ++----------------- .../jnr/ffi/struct/AsciiStringFieldTest.java | 2 +- 3 files changed, 43 insertions(+), 38 deletions(-) create mode 100644 src/main/java/jnr/ffi/struct/StringField.java 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/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index 4c1f15930..6ad07293d 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -2168,42 +2168,9 @@ public Enum(Class enumClass) { } } - abstract public class String extends Field { - protected final Charset charset; - protected final int length; - - protected String(NativeType nativeType, int length, Charset cs) { - super(Struct.this, nativeType); - this.length = length; - this.charset = cs; - } - protected String(int size, int align, int length, Charset cs) { - super(Struct.this, size, align); - this.length = length; - this.charset = cs; - } - protected String(int size, int align, Offset offset, int length, Charset cs) { - super(Struct.this, 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 class UTFString extends StringField { public UTFString(int length, Charset cs) { - super(length * 8, 8, length, cs); // FIXME: This won't work for non-ASCII + super(Struct.this,length * 8, 8, length, cs); // FIXME: This won't work for non-ASCII } protected jnr.ffi.Pointer getStringMemory() { @@ -2231,11 +2198,11 @@ public AsciiString(int size) { } } - public class UTFStringRef extends String { + public class UTFStringRef extends StringField { private jnr.ffi.Pointer valueHolder; public UTFStringRef(int length, Charset cs) { - super(NativeType.ADDRESS, length, cs); + super(Struct.this, NativeType.ADDRESS, length, cs); } public UTFStringRef(Charset cs) { diff --git a/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java b/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java index 5f45f00a6..82b7c2210 100644 --- a/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java +++ b/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java @@ -39,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 AsciiString(32); public StringFieldStruct() { super(runtime); From ed6d7a53a62db701012609ff8e9cea7dfe033021 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 2 Sep 2017 22:44:11 +0300 Subject: [PATCH 11/11] Move UTFString to struct package --- src/main/java/jnr/ffi/struct/AsciiString.java | 10 +++++ src/main/java/jnr/ffi/struct/Struct.java | 40 +++++++++---------- src/main/java/jnr/ffi/struct/UTF8String.java | 10 +++++ src/main/java/jnr/ffi/struct/UTFString.java | 21 ++++++++++ .../jnr/ffi/struct/AsciiStringFieldTest.java | 2 +- .../jnr/ffi/struct/UTF8StringFieldTest.java | 4 +- 6 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 src/main/java/jnr/ffi/struct/AsciiString.java create mode 100644 src/main/java/jnr/ffi/struct/UTF8String.java create mode 100644 src/main/java/jnr/ffi/struct/UTFString.java 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/Struct.java b/src/main/java/jnr/ffi/struct/Struct.java index 6ad07293d..7c416899e 100755 --- a/src/main/java/jnr/ffi/struct/Struct.java +++ b/src/main/java/jnr/ffi/struct/Struct.java @@ -630,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; @@ -2168,33 +2168,33 @@ public Enum(Class enumClass) { } } - public class UTFString extends StringField { + /** + * Use {@link jnr.ffi.struct.UTFString} instead + */ + @Deprecated + public class UTFString extends jnr.ffi.struct.UTFString { public UTFString(int length, Charset cs) { - super(Struct.this,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); } } 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/test/java/jnr/ffi/struct/AsciiStringFieldTest.java b/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java index 82b7c2210..de78e2c16 100644 --- a/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java +++ b/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java @@ -39,7 +39,7 @@ public class AsciiStringFieldTest { public AsciiStringFieldTest() { } public class StringFieldStruct extends Struct { - public final StringField 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/UTF8StringFieldTest.java b/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java index a48288098..91d5bcb11 100644 --- a/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java +++ b/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java @@ -40,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); @@ -87,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);