diff --git a/java_console/inifile/src/com/opensr5/ini/field/EnumIniField.java b/java_console/inifile/src/com/opensr5/ini/field/EnumIniField.java index 1aa0f4d1f8..a13af85f6c 100644 --- a/java_console/inifile/src/com/opensr5/ini/field/EnumIniField.java +++ b/java_console/inifile/src/com/opensr5/ini/field/EnumIniField.java @@ -14,14 +14,15 @@ public class EnumIniField extends IniField { private final FieldType type; private final List enums; private final int bitPosition; - private final int bitSize; + // weird format where 'one bit' width means 0 and "two bits" means "1" + private final int bitSize0; - public EnumIniField(String name, int offset, FieldType type, List enums, int bitPosition, int bitSize) { + public EnumIniField(String name, int offset, FieldType type, List enums, int bitPosition, int bitSize0) { super(name, offset); this.type = type; this.enums = enums; this.bitPosition = bitPosition; - this.bitSize = bitSize; + this.bitSize0 = bitSize0; } @Override @@ -33,8 +34,8 @@ public class EnumIniField extends IniField { return bitPosition; } - public int getBitSize() { - return bitSize; + public int getBitSize0() { + return bitSize0; } public List getEnums() { @@ -48,7 +49,7 @@ public class EnumIniField extends IniField { @Override public String getValue(ConfigurationImage image) { int ordinal = getByteBuffer(image).getInt(); - ordinal = getBitRange(ordinal, bitPosition, bitSize); + ordinal = getBitRange(ordinal, bitPosition, bitSize0 + 1); if (ordinal >= enums.size()) throw new IllegalStateException(ordinal + " in " + getName()); @@ -72,7 +73,7 @@ public class EnumIniField extends IniField { if (ordinal == -1) throw new IllegalArgumentException("Not found " + v); int value = getByteBuffer(image).getInt(); - value = setBitRange(value, ordinal, bitPosition, bitSize); + value = setBitRange(value, ordinal, bitPosition, bitSize0 + 1); getByteBuffer(image).putInt(value); } @@ -84,23 +85,25 @@ public class EnumIniField extends IniField { ", type=" + type + ", enums=" + enums + ", bitPosition=" + bitPosition + - ", bitSize=" + bitSize + + ", bitSize=" + bitSize0 + '}'; } public static int setBitRange(int value, int ordinal, int bitPosition, int bitSize) { + if (ordinal >= (1 << bitSize)) + throw new IllegalArgumentException("Ordinal overflow " + ordinal + " does not fit in " + bitSize + " bit(s)"); int num = ((1 << bitSize) - 1) << bitPosition; int clearBitRange = value & ~num; - return (byte) (clearBitRange + (ordinal << bitPosition)); + return (clearBitRange + (ordinal << bitPosition)); } public static boolean getBit(int ordinal, int bitPosition) { - return getBitRange(ordinal, bitPosition, 0) == 1; + return getBitRange(ordinal, bitPosition, 1) == 1; } public static int getBitRange(int ordinal, int bitPosition, int bitSize) { ordinal = ordinal >> bitPosition; - ordinal = ordinal & ((1 << (bitSize + 1)) - 1); + ordinal = ordinal & ((1 << (bitSize)) - 1); return ordinal; } @@ -115,10 +118,10 @@ public class EnumIniField extends IniField { if (bitPositions.length != 2) throw new IllegalStateException("Bit position " + bitRange); int bitPosition = Integer.parseInt(bitPositions[0]); - int bitSize = Integer.parseInt(bitPositions[1]) - bitPosition; + int bitSize0 = Integer.parseInt(bitPositions[1]) - bitPosition; List enums = list.subList(5, list.size()); - return new EnumIniField(name, offset, type, enums, bitPosition, bitSize); + return new EnumIniField(name, offset, type, enums, bitPosition, bitSize0); } } diff --git a/java_console/inifile/src/com/opensr5/ini/test/IniFileReaderTest.java b/java_console/inifile/src/com/opensr5/ini/test/IniFileReaderTest.java index f8c71ee433..b0219d8e25 100644 --- a/java_console/inifile/src/com/opensr5/ini/test/IniFileReaderTest.java +++ b/java_console/inifile/src/com/opensr5/ini/test/IniFileReaderTest.java @@ -12,7 +12,6 @@ import org.junit.Test; import java.io.ByteArrayInputStream; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; /** * Andrey Belomutskiy, (c) 2013-2020 @@ -104,26 +103,28 @@ public class IniFileReaderTest { @Test public void testSetBits() { - assertEquals((byte) 0xFE, EnumIniField.setBitRange((byte) 0xFF, 0, 0, 1)); - assertEquals((byte) 0xF0, EnumIniField.setBitRange((byte) 0xFF, 0, 0, 4)); - assertEquals((byte) 0x0F, EnumIniField.setBitRange((byte) 0xFF, 0, 4, 4)); + assertEquals(0xFE, EnumIniField.setBitRange(0xFF, 0, 0, 1)); + assertEquals(0xF0, EnumIniField.setBitRange(0xFF, 0, 0, 4)); + assertEquals(0x0F, EnumIniField.setBitRange(0xFF, 0, 4, 4)); - assertEquals((byte) 1, EnumIniField.setBitRange((byte) 0xFF, 3, 0, 1)); - assertEquals((byte) -13, EnumIniField.setBitRange((byte) 0xFF, 3, 0, 4)); - assertEquals((byte) 0x3F, EnumIniField.setBitRange((byte) 0xFF, 3, 4, 4)); + assertEquals(0xff, EnumIniField.setBitRange(0xFF, 3, 0, 2)); + assertEquals(0xF3, EnumIniField.setBitRange(0xFF, 3, 0, 4)); + assertEquals(0x3F, EnumIniField.setBitRange(0xFF, 3, 4, 4)); + + assertEquals(0x400, EnumIniField.setBitRange(0, 1, 10, 1)); } @Test public void testBitLogic() { - assertEquals(4, EnumIniField.getBitRange(4, 0, 7)); - assertEquals(4, EnumIniField.getBitRange(4, 0, 2)); - assertEquals(0, EnumIniField.getBitRange(4, 0, 1)); - assertEquals(3, EnumIniField.getBitRange(7, 0, 1)); + assertEquals(4, EnumIniField.getBitRange(4, 0, 8)); + assertEquals(4, EnumIniField.getBitRange(4, 0, 3)); + assertEquals(0, EnumIniField.getBitRange(4, 0, 2)); + assertEquals(3, EnumIniField.getBitRange(7, 0, 2)); assertEquals(true, EnumIniField.getBit(0xff, 0)); assertEquals(true, EnumIniField.getBit(0xf0, 4)); - assertEquals(2, EnumIniField.getBitRange(0xf0, 3, 1)); + assertEquals(2, EnumIniField.getBitRange(0xf0, 3, 2)); } @Test @@ -138,7 +139,7 @@ public class IniFileReaderTest { EnumIniField field = (EnumIniField) model.allIniFields.get("name"); assertEquals(3, field.getBitPosition()); - assertEquals(2, field.getBitSize()); + assertEquals(2, field.getBitSize0()); assertEquals(2, field.getEnums().size()); }