From e49893754ddf3b910af6d697dc87c69fbc9d15f0 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 30 Jun 2017 23:11:26 +0300 Subject: [PATCH 01/10] Tests for negative values of enums --- src/test/java/jnr/ffi/struct/EnumTest.java | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/test/java/jnr/ffi/struct/EnumTest.java b/src/test/java/jnr/ffi/struct/EnumTest.java index a361bd96d..0043c62fa 100644 --- a/src/test/java/jnr/ffi/struct/EnumTest.java +++ b/src/test/java/jnr/ffi/struct/EnumTest.java @@ -41,6 +41,47 @@ public enum TestEnum { B, MAGIC } + + public enum ByteNegativeEnum + implements EnumMapper.IntegerEnum { + NEGATIVE(0xF0); + + final int value; + + ByteNegativeEnum(int value) {this.value = value;} + + @Override + public int intValue() { + return value; + } + } + + public enum ShortNegativeEnum + implements EnumMapper.IntegerEnum { + NEGATIVE(0xF000); + + final int value; + + ShortNegativeEnum(int value) {this.value = value;} + + @Override + public int intValue() { + return value; + } + } + + public enum IntNegativeEnum { + NEGATIVE(0xF00000L); + + final long value; + + IntNegativeEnum(long value) {this.value = value;} + + public long longValue() { + return value; + } + } + public class struct1 extends Struct { public final Enum8 b = new Enum8(TestEnum.class); public final Enum16 s = new Enum16(TestEnum.class); @@ -130,6 +171,24 @@ public LongAlign() { } } + public static class Enum8FieldStruct extends Struct { + public final Enum8 value = new Enum8(ByteNegativeEnum.class); + public Enum8FieldStruct() { + super(runtime); + } + } + public static class Enum16FieldStruct extends Struct { + public final Enum16 value = new Enum16(ShortNegativeEnum.class); + public Enum16FieldStruct() { + super(runtime); + } + } + public static class Enum32FieldStruct extends Struct { + public final Enum32 value = new Enum32(IntNegativeEnum.class); + public Enum32FieldStruct() { + super(runtime); + } + } @Test public void testInt8InitialValue() { struct1 s = new struct1(); assertEquals("default value not zero", TestEnum.ZERO, s.b.get()); @@ -212,4 +271,28 @@ public void alignSignedLongField() { assertEquals("native long field not aligned", MAGIC, testlib.struct_align_SignedLong(s)); } + + @Test + public void byteEnumFieldWithNegativeValue() + { + Enum8FieldStruct struct = new Enum8FieldStruct(); + struct.value.set(ByteNegativeEnum.NEGATIVE); + assertEquals("negative Enum8 value conversation failed", ByteNegativeEnum.NEGATIVE, struct.value.get()); + } + + @Test + public void shortEnumFieldWithNegativeValue() + { + Enum16FieldStruct struct = new Enum16FieldStruct(); + struct.value.set(ShortNegativeEnum.NEGATIVE); + assertEquals("negative Enum8 value conversation failed", ShortNegativeEnum.NEGATIVE, struct.value.get()); + } + + @Test + public void intEnumFieldWithNegativeValue() + { + Enum32FieldStruct struct = new Enum32FieldStruct(); + struct.value.set(IntNegativeEnum.NEGATIVE); + assertEquals("negative Enum8 value conversation failed", IntNegativeEnum.NEGATIVE, struct.value.get()); + } } From b85a6a5f2701f2bde5760dc685ead9cfb853663b Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 30 Jun 2017 23:14:24 +0300 Subject: [PATCH 02/10] Fix Enum8 negative values issue. --- src/main/java/jnr/ffi/Struct.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/jnr/ffi/Struct.java b/src/main/java/jnr/ffi/Struct.java index f235472cb..149d4d05a 100755 --- a/src/main/java/jnr/ffi/Struct.java +++ b/src/main/java/jnr/ffi/Struct.java @@ -2183,7 +2183,8 @@ public void set(java.lang.Number value) { */ @Override public final int intValue() { - return getMemory().getByte(offset()); + short value = getMemory().getByte(offset()); + return value < 0 ? (short) ((value & 0x7F) + 0x80) : value; } } From 6291ad0dab51e6e0e6dc8c47fade86097e0927f1 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 30 Jun 2017 23:16:13 +0300 Subject: [PATCH 03/10] Fix Enum16 negative values issue. --- src/main/java/jnr/ffi/Struct.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/jnr/ffi/Struct.java b/src/main/java/jnr/ffi/Struct.java index 149d4d05a..009dc0585 100755 --- a/src/main/java/jnr/ffi/Struct.java +++ b/src/main/java/jnr/ffi/Struct.java @@ -2203,7 +2203,8 @@ public void set(java.lang.Number value) { } @Override public final int intValue() { - return getMemory().getShort(offset()); + int value = getMemory().getShort(offset()); + return value < 0 ? (value & 0x7FFF) + 0x8000 : value; } } From d28ab35d43d01bb052bd2e18b0424941a575891b Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 30 Jun 2017 23:19:20 +0300 Subject: [PATCH 04/10] Fix Enum32 negative values issue. --- src/main/java/jnr/ffi/Struct.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/jnr/ffi/Struct.java b/src/main/java/jnr/ffi/Struct.java index 009dc0585..a4fbfd65f 100755 --- a/src/main/java/jnr/ffi/Struct.java +++ b/src/main/java/jnr/ffi/Struct.java @@ -2213,7 +2213,7 @@ public Enum32(Class enumClass) { super(NativeType.SINT, enumClass); } public final E get() { - return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue())); + return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(longValue())); } public final void set(E value) { getMemory().putInt(offset(), EnumMapper.getInstance(enumClass).intValue(value)); @@ -2223,7 +2223,13 @@ public void set(java.lang.Number value) { } @Override public final int intValue() { - return getMemory().getInt(offset()); + return (int) longValue(); + } + + @Override + public long longValue() { + long value = getMemory().getInt(offset()); + return value < 0 ? (long)((value & 0x7FFFFFFFL) + 0x80000000L) : value; } } From 153cd0f9eaa45fc0b92047cc07be4ff5194763c1 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 30 Jun 2017 23:38:28 +0300 Subject: [PATCH 05/10] Test for `Enum64` field with value that is bigger than max int. --- src/test/java/jnr/ffi/struct/EnumTest.java | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/java/jnr/ffi/struct/EnumTest.java b/src/test/java/jnr/ffi/struct/EnumTest.java index 0043c62fa..67bbc4d82 100644 --- a/src/test/java/jnr/ffi/struct/EnumTest.java +++ b/src/test/java/jnr/ffi/struct/EnumTest.java @@ -82,6 +82,20 @@ public long longValue() { } } + public enum LongEnum { + BIGGER_THAN_INT(0xFF00000000000000L); + + private final long value; + + LongEnum(long value) { + this.value = value; + } + + public long longValue() { + return value; + } + } + public class struct1 extends Struct { public final Enum8 b = new Enum8(TestEnum.class); public final Enum16 s = new Enum16(TestEnum.class); @@ -189,6 +203,12 @@ public Enum32FieldStruct() { super(runtime); } } + public static class Enum64FieldStruct extends Struct { + public final Enum64 value = new Enum64(LongEnum.class); + public Enum64FieldStruct() { + super(runtime); + } + } @Test public void testInt8InitialValue() { struct1 s = new struct1(); assertEquals("default value not zero", TestEnum.ZERO, s.b.get()); @@ -295,4 +315,11 @@ public void intEnumFieldWithNegativeValue() struct.value.set(IntNegativeEnum.NEGATIVE); assertEquals("negative Enum8 value conversation failed", IntNegativeEnum.NEGATIVE, struct.value.get()); } + + @Test + public void longEnumField(){ + Enum64FieldStruct struct = new Enum64FieldStruct(); + struct.value.set(LongEnum.BIGGER_THAN_INT); + assertEquals("long Enum64 value conversation failed", LongEnum.BIGGER_THAN_INT, struct.value.get()); + } } From b917f25178c01fd44064c53e48ab0674de7920eb Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 30 Jun 2017 23:40:07 +0300 Subject: [PATCH 06/10] Fix Enum64 bigger than int values issue --- src/main/java/jnr/ffi/Struct.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/jnr/ffi/Struct.java b/src/main/java/jnr/ffi/Struct.java index a4fbfd65f..c85126a11 100755 --- a/src/main/java/jnr/ffi/Struct.java +++ b/src/main/java/jnr/ffi/Struct.java @@ -2238,10 +2238,10 @@ public Enum64(Class enumClass) { super(NativeType.SLONGLONG, enumClass); } public final E get() { - return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue())); + return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(longValue())); } public final void set(E value) { - getMemory().putLongLong(offset(), EnumMapper.getInstance(enumClass).intValue(value)); + getMemory().putLongLong(offset(), EnumMapper.getInstance(enumClass).longValue(value)); } public void set(java.lang.Number value) { getMemory().putLongLong(offset(), value.longValue()); From 54ba754189aed03a75b48cafca60069781257a5e Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Fri, 30 Jun 2017 23:41:17 +0300 Subject: [PATCH 07/10] Fix typos in assertations' messages of `EnumTest`. --- src/test/java/jnr/ffi/struct/EnumTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/jnr/ffi/struct/EnumTest.java b/src/test/java/jnr/ffi/struct/EnumTest.java index 67bbc4d82..54927dd48 100644 --- a/src/test/java/jnr/ffi/struct/EnumTest.java +++ b/src/test/java/jnr/ffi/struct/EnumTest.java @@ -305,7 +305,7 @@ public void shortEnumFieldWithNegativeValue() { Enum16FieldStruct struct = new Enum16FieldStruct(); struct.value.set(ShortNegativeEnum.NEGATIVE); - assertEquals("negative Enum8 value conversation failed", ShortNegativeEnum.NEGATIVE, struct.value.get()); + assertEquals("negative Enum16 value conversation failed", ShortNegativeEnum.NEGATIVE, struct.value.get()); } @Test @@ -313,7 +313,7 @@ public void intEnumFieldWithNegativeValue() { Enum32FieldStruct struct = new Enum32FieldStruct(); struct.value.set(IntNegativeEnum.NEGATIVE); - assertEquals("negative Enum8 value conversation failed", IntNegativeEnum.NEGATIVE, struct.value.get()); + assertEquals("negative Enum32 value conversation failed", IntNegativeEnum.NEGATIVE, struct.value.get()); } @Test From dd4df163102af503ca2be10d2c0b016df3ecc330 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 1 Jul 2017 00:58:09 +0300 Subject: [PATCH 08/10] Correct test name for `Enum64` --- src/test/java/jnr/ffi/struct/EnumTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/jnr/ffi/struct/EnumTest.java b/src/test/java/jnr/ffi/struct/EnumTest.java index 54927dd48..b0b7e24bd 100644 --- a/src/test/java/jnr/ffi/struct/EnumTest.java +++ b/src/test/java/jnr/ffi/struct/EnumTest.java @@ -317,7 +317,7 @@ public void intEnumFieldWithNegativeValue() } @Test - public void longEnumField(){ + public void longLongEnumField(){ Enum64FieldStruct struct = new Enum64FieldStruct(); struct.value.set(LongEnum.BIGGER_THAN_INT); assertEquals("long Enum64 value conversation failed", LongEnum.BIGGER_THAN_INT, struct.value.get()); From f010e9e2ec4945923d8e49ad7396d14737a4072c Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 1 Jul 2017 01:11:58 +0300 Subject: [PATCH 09/10] Test for `EnumLong` 8-byte value. --- src/test/java/jnr/ffi/struct/EnumTest.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/test/java/jnr/ffi/struct/EnumTest.java b/src/test/java/jnr/ffi/struct/EnumTest.java index b0b7e24bd..ef0b182e6 100644 --- a/src/test/java/jnr/ffi/struct/EnumTest.java +++ b/src/test/java/jnr/ffi/struct/EnumTest.java @@ -209,6 +209,12 @@ public Enum64FieldStruct() { super(runtime); } } + public static class EnumLongFieldStruct extends Struct { + public final EnumLong value = new EnumLong(LongEnum.class); + public EnumLongFieldStruct() { + super(runtime); + } + } @Test public void testInt8InitialValue() { struct1 s = new struct1(); assertEquals("default value not zero", TestEnum.ZERO, s.b.get()); @@ -322,4 +328,12 @@ public void longLongEnumField(){ struct.value.set(LongEnum.BIGGER_THAN_INT); assertEquals("long Enum64 value conversation failed", LongEnum.BIGGER_THAN_INT, struct.value.get()); } + @Test + public void longEnumFieldX64(){ + if (runtime.longSize() == 8) { + EnumLongFieldStruct struct = new EnumLongFieldStruct(); + struct.value.set(LongEnum.BIGGER_THAN_INT); + assertEquals("long EnumLong value conversation failed", LongEnum.BIGGER_THAN_INT, struct.value.get()); + } + } } From 94dee0905d1c2176a1d6196f0a74f446e28d0498 Mon Sep 17 00:00:00 2001 From: Andrew Yefanov <1134togo@gmail.com> Date: Sat, 1 Jul 2017 01:13:25 +0300 Subject: [PATCH 10/10] Fixed `EnumLong` field issue when long size is 8 bytes. --- src/main/java/jnr/ffi/Struct.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/jnr/ffi/Struct.java b/src/main/java/jnr/ffi/Struct.java index c85126a11..9bc60a563 100755 --- a/src/main/java/jnr/ffi/Struct.java +++ b/src/main/java/jnr/ffi/Struct.java @@ -2262,10 +2262,10 @@ public EnumLong(Class enumClass) { } public final E get() { - return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue())); + return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(longValue())); } public final void set(E value) { - getMemory().putNativeLong(offset(), EnumMapper.getInstance(enumClass).intValue(value)); + set(EnumMapper.getInstance(enumClass).longValue(value)); } public void set(java.lang.Number value) { getMemory().putNativeLong(offset(), value.longValue());