rusefi-full/java_console/inifile/src/com/opensr5/ini/field/EnumIniField.java

108 lines
3.4 KiB
Java

package com.opensr5.ini.field;
import com.opensr5.ConfigurationImage;
import com.rusefi.config.FieldType;
import com.rusefi.tune.xml.Constant;
import org.jetbrains.annotations.NotNull;
import javax.management.ObjectName;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.List;
public class EnumIniField extends IniField {
private final FieldType type;
private final List<String> enums;
private final int bitPosition;
private final int bitSize;
public EnumIniField(String name, int offset, FieldType type, List<String> enums, int bitPosition, int bitSize) {
super(name, offset);
this.type = type;
this.enums = enums;
this.bitPosition = bitPosition;
this.bitSize = bitSize;
}
public int getBitPosition() {
return bitPosition;
}
public int getBitSize() {
return bitSize;
}
public List<String> getEnums() {
return enums;
}
public FieldType getType() {
return type;
}
@Override
public String getValue(ConfigurationImage image) {
int ordinal = getByteBuffer(image).getInt();
ordinal = getBitRange(ordinal, bitPosition, bitSize);
if (ordinal >= enums.size())
throw new IllegalStateException(ordinal + " in " + getName());
return enums.get(ordinal);
}
@NotNull
private ByteBuffer getByteBuffer(ConfigurationImage image) {
return image.getByteBuffer(getOffset(), 4);
}
private static boolean isQuoted(String q) {
final int len = q.length();
return (len >= 2 && q.charAt(0) == '"' && q.charAt(len - 1) == '"');
}
@Override
public void setValue(ConfigurationImage image, Constant constant) {
String v = constant.getValue();
int ordinal = enums.indexOf(isQuoted(v) ? ObjectName.unquote(v) : v);
if (ordinal == -1)
throw new IllegalArgumentException("Not found " + v);
int value = getByteBuffer(image).getInt();
value = setBitRange(value, ordinal, bitPosition, bitSize);
getByteBuffer(image).putInt(value);
}
public static int setBitRange(int value, int ordinal, int bitPosition, int bitSize) {
int num = ((1 << bitSize) - 1) << bitPosition;
int clearBitRange = value & ~num;
return (byte) (clearBitRange + (ordinal << bitPosition));
}
public static boolean getBit(int ordinal, int bitPosition) {
return getBitRange(ordinal, bitPosition, 0) == 1;
}
public static int getBitRange(int ordinal, int bitPosition, int bitSize) {
ordinal = ordinal >> bitPosition;
ordinal = ordinal & ((1 << (bitSize + 1)) - 1);
return ordinal;
}
public static EnumIniField parse(LinkedList<String> list) {
String name = list.get(0);
FieldType type = FieldType.parseTs(list.get(2));
int offset = Integer.parseInt(list.get(3));
String bitRange = list.get(4);
bitRange = bitRange.replaceAll("[\\]\\[:]", " ").trim();
String bitPositions[] = bitRange.split(" ");
if (bitPositions.length != 2)
throw new IllegalStateException("Bit position " + bitRange);
int bitPosition = Integer.parseInt(bitPositions[0]);
int bitSize = Integer.parseInt(bitPositions[1]) - bitPosition;
List<String> enums = list.subList(5, list.size());
return new EnumIniField(name, offset, type, enums, bitPosition, bitSize);
}
}