can-log-tools/reader/src/main/java/com/rusefi/can/reader/dbc/DbcField.java

139 lines
4.1 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;
try {
while (!tokens[index - 1].equals(":"))
index++;
} catch (ArrayIndexOutOfBoundsException e) {
throw new IllegalStateException("While parsing [" + line + "]", e);
}
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;
}
public boolean coversByte(int byteIndex) {
int startBit = byteIndex * 8;
if (startOffset > startBit)
return false;
if (startOffset + length < startBit + 8)
return false;
return true;
}
}