126 lines
3.7 KiB
Java
126 lines
3.7 KiB
Java
package com.rusefi.can.reader.dbc;
|
|
|
|
import com.rusefi.can.CANPacket;
|
|
|
|
public class DbcField {
|
|
private String name;
|
|
private final int startOffset;
|
|
private final int length;
|
|
private final double mult;
|
|
private final double offset;
|
|
private String category;
|
|
private final boolean isBigEndian;
|
|
private boolean isNiceName;
|
|
|
|
public DbcField(String name, int startOffset, int length, double mult, double offset, String category, boolean isBigEndian) {
|
|
this.name = name;
|
|
this.startOffset = startOffset;
|
|
this.length = length;
|
|
this.mult = mult;
|
|
this.offset = offset;
|
|
this.category = category;
|
|
this.isBigEndian = isBigEndian;
|
|
}
|
|
|
|
public static DbcField parseField(DbcPacket parent, String line) {
|
|
line = DbcFile.replaceSpecialWithSpaces(line);
|
|
String[] tokens = line.split(" ");
|
|
if (tokens.length < 2)
|
|
return null;
|
|
String name = tokens[1];
|
|
int index = 1;
|
|
while (!tokens[index - 1].equals(":"))
|
|
index++;
|
|
|
|
|
|
if (DbcFile.debugEnabled)
|
|
System.out.println(line);
|
|
int startOffset;
|
|
try {
|
|
startOffset = Integer.parseInt(tokens[index]);
|
|
} catch (NumberFormatException e) {
|
|
throw new IllegalStateException("While " + line, e);
|
|
}
|
|
int length = Integer.parseInt(tokens[index + 1]);
|
|
int endiannessCode = Integer.parseInt(tokens[index + 2]);
|
|
if (endiannessCode != 0 && endiannessCode != 1)
|
|
throw new IllegalStateException("Unexpected endiannessCode " + endiannessCode);
|
|
boolean isBigEndian = endiannessCode == 0;
|
|
|
|
double mult = Double.parseDouble(tokens[index + 3]);
|
|
double offset = Double.parseDouble(tokens[index + 4]);
|
|
|
|
return new DbcField(name, startOffset, length, mult, offset, parent.getName(), isBigEndian);
|
|
}
|
|
|
|
public String getCategory() {
|
|
return category;
|
|
}
|
|
|
|
public boolean isNiceName() {
|
|
return isNiceName;
|
|
}
|
|
|
|
public String getName() {
|
|
return name;
|
|
}
|
|
|
|
public int getStartOffset() {
|
|
return startOffset;
|
|
}
|
|
|
|
public int getLength() {
|
|
return length;
|
|
}
|
|
|
|
public double getMult() {
|
|
return mult;
|
|
}
|
|
|
|
public double getOffset() {
|
|
return offset;
|
|
}
|
|
|
|
public boolean isBigEndian() {
|
|
return isBigEndian;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "DbcField{" +
|
|
"name='" + name + '\'' +
|
|
", startOffset=" + startOffset +
|
|
", length=" + length +
|
|
", mult=" + mult +
|
|
", isBigEndian=" + isBigEndian +
|
|
'}';
|
|
}
|
|
|
|
public static int getBitRange(byte[] data, int bitIndex, int bitWidth, boolean isBigEndian) {
|
|
if (bitIndex < 0)
|
|
throw new IllegalArgumentException("Huh? " + bitIndex + " " + bitWidth);
|
|
int byteIndex = bitIndex >> 3;
|
|
int shift = bitIndex - byteIndex * 8;
|
|
if (byteIndex >= data.length)
|
|
return 0;
|
|
int value = data[byteIndex] & 0xff;
|
|
if (shift + bitWidth > 8) {
|
|
int otherByteIndex = (isBigEndian ? -1 : +1) + byteIndex;
|
|
if (otherByteIndex < 0 || otherByteIndex >= data.length)
|
|
return 0;
|
|
value = value + data[otherByteIndex] * 256;
|
|
}
|
|
int mask = (1 << bitWidth) - 1;
|
|
return (value >> shift) & mask;
|
|
}
|
|
|
|
public double getValue(CANPacket packet) {
|
|
return getBitRange(packet.getData(), startOffset, length, isBigEndian) * mult + offset;
|
|
}
|
|
|
|
public void rename(String niceName) {
|
|
name = niceName;
|
|
isNiceName = true;
|
|
}
|
|
}
|