Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Struct Enum fields #127

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
24 changes: 16 additions & 8 deletions src/main/java/jnr/ffi/Struct.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand All @@ -2202,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;
}
}

Expand All @@ -2211,7 +2213,7 @@ public Enum32(Class<E> 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));
Expand All @@ -2221,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;
}
}

Expand All @@ -2230,10 +2238,10 @@ public Enum64(Class<E> 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());
Expand All @@ -2254,10 +2262,10 @@ public EnumLong(Class<E> 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());
Expand Down
124 changes: 124 additions & 0 deletions src/test/java/jnr/ffi/struct/EnumTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,61 @@ 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 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<TestEnum> b = new Enum8<TestEnum>(TestEnum.class);
public final Enum16<TestEnum> s = new Enum16<TestEnum>(TestEnum.class);
Expand Down Expand Up @@ -130,6 +185,36 @@ public LongAlign() {
}

}
public static class Enum8FieldStruct extends Struct {
public final Enum8<ByteNegativeEnum> value = new Enum8<ByteNegativeEnum>(ByteNegativeEnum.class);
public Enum8FieldStruct() {
super(runtime);
}
}
public static class Enum16FieldStruct extends Struct {
public final Enum16<ShortNegativeEnum> value = new Enum16<ShortNegativeEnum>(ShortNegativeEnum.class);
public Enum16FieldStruct() {
super(runtime);
}
}
public static class Enum32FieldStruct extends Struct {
public final Enum32<IntNegativeEnum> value = new Enum32<IntNegativeEnum>(IntNegativeEnum.class);
public Enum32FieldStruct() {
super(runtime);
}
}
public static class Enum64FieldStruct extends Struct {
public final Enum64<LongEnum> value = new Enum64<LongEnum>(LongEnum.class);
public Enum64FieldStruct() {
super(runtime);
}
}
public static class EnumLongFieldStruct extends Struct {
public final EnumLong<LongEnum> value = new EnumLong<LongEnum>(LongEnum.class);
public EnumLongFieldStruct() {
super(runtime);
}
}
@Test public void testInt8InitialValue() {
struct1 s = new struct1();
assertEquals("default value not zero", TestEnum.ZERO, s.b.get());
Expand Down Expand Up @@ -212,4 +297,43 @@ 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 Enum16 value conversation failed", ShortNegativeEnum.NEGATIVE, struct.value.get());
}

@Test
public void intEnumFieldWithNegativeValue()
{
Enum32FieldStruct struct = new Enum32FieldStruct();
struct.value.set(IntNegativeEnum.NEGATIVE);
assertEquals("negative Enum32 value conversation failed", IntNegativeEnum.NEGATIVE, struct.value.get());
}

@Test
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());
}
@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());
}
}
}