2022-06-20 14:29:02 -07:00
|
|
|
package com.rusefi.can.reader.dbc;
|
|
|
|
|
2022-08-26 17:11:21 -07:00
|
|
|
import com.rusefi.can.LoggingStrategy;
|
|
|
|
import com.rusefi.sensor_logs.BinaryLogEntry;
|
|
|
|
|
2022-06-20 14:29:02 -07:00
|
|
|
import java.io.BufferedReader;
|
2022-06-26 09:15:18 -07:00
|
|
|
import java.io.FileReader;
|
2022-06-20 14:29:02 -07:00
|
|
|
import java.io.IOException;
|
2022-09-12 23:01:23 -07:00
|
|
|
import java.util.ArrayList;
|
2022-08-19 20:16:59 -07:00
|
|
|
import java.util.LinkedHashMap;
|
2022-06-20 14:29:02 -07:00
|
|
|
import java.util.List;
|
2022-08-19 20:16:59 -07:00
|
|
|
import java.util.Objects;
|
2022-06-20 14:29:02 -07:00
|
|
|
|
|
|
|
public class DbcFile {
|
2022-08-19 20:16:59 -07:00
|
|
|
public final LinkedHashMap<Integer, DbcPacket> packets = new LinkedHashMap<>();
|
2022-06-20 14:29:02 -07:00
|
|
|
|
2022-08-27 16:57:29 -07:00
|
|
|
public static final boolean debugEnabled = false;
|
2022-06-26 09:15:18 -07:00
|
|
|
|
2022-08-26 17:11:21 -07:00
|
|
|
private List<BinaryLogEntry> list;
|
|
|
|
|
2022-09-12 23:01:23 -07:00
|
|
|
boolean logOnlyTranslatedFields;
|
|
|
|
|
|
|
|
public DbcFile(boolean logOnlyTranslatedFields) {
|
|
|
|
this.logOnlyTranslatedFields = logOnlyTranslatedFields;
|
|
|
|
}
|
|
|
|
|
2022-06-26 09:15:18 -07:00
|
|
|
public static DbcFile readFromFile(String fileName) throws IOException {
|
2022-11-10 05:14:49 -08:00
|
|
|
System.out.println("Reading DBC file from " + fileName + "...");
|
2022-09-12 23:01:23 -07:00
|
|
|
DbcFile dbc = new DbcFile(LoggingStrategy.LOG_ONLY_TRANSLATED_FIELDS);
|
2022-06-26 09:15:18 -07:00
|
|
|
{
|
|
|
|
BufferedReader reader = new BufferedReader(new FileReader(fileName));
|
|
|
|
dbc.read(reader);
|
|
|
|
}
|
|
|
|
return dbc;
|
|
|
|
}
|
|
|
|
|
2022-06-20 14:29:02 -07:00
|
|
|
public void read(BufferedReader reader) throws IOException {
|
2022-08-16 22:01:48 -07:00
|
|
|
DbcPacket currentPacket = null;
|
2022-06-20 14:29:02 -07:00
|
|
|
String line;
|
2022-08-24 13:44:51 -07:00
|
|
|
int lineIndex = -1;
|
2022-06-20 14:29:02 -07:00
|
|
|
while ((line = reader.readLine()) != null) {
|
2022-08-24 13:44:51 -07:00
|
|
|
lineIndex++;
|
2022-06-20 14:29:02 -07:00
|
|
|
line = line.trim();
|
|
|
|
if (line.startsWith("BO_")) {
|
2022-08-19 20:16:59 -07:00
|
|
|
purgePacket(currentPacket);
|
2022-06-20 14:29:02 -07:00
|
|
|
line = line.replaceAll(":", "");
|
|
|
|
String[] tokens = line.split(" ");
|
2022-09-12 23:26:02 -07:00
|
|
|
if (tokens.length < 3) {
|
|
|
|
// skipping header line
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
long decId = Long.parseLong(tokens[1]);
|
|
|
|
if (decId > 2_000_000_000) {
|
|
|
|
System.err.println("Huh? Skipping ID=" + decId);
|
|
|
|
continue;
|
|
|
|
}
|
2022-08-16 22:01:48 -07:00
|
|
|
String packetName = tokens[2];
|
2022-09-12 23:26:02 -07:00
|
|
|
currentPacket = new DbcPacket((int) decId, packetName);
|
2022-08-19 20:16:59 -07:00
|
|
|
} else if (line.startsWith("CM_")) {
|
|
|
|
purgePacket(currentPacket);
|
|
|
|
line = replaceSpecialWithSpaces(line);
|
|
|
|
String[] tokens = line.split(" ");
|
2022-08-24 13:44:51 -07:00
|
|
|
if (tokens.length == 1) {
|
|
|
|
// skipping header line
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (tokens.length < 4)
|
|
|
|
throw new IllegalStateException("Failing to parse comment: " + line + " at " + lineIndex);
|
2022-08-19 20:16:59 -07:00
|
|
|
int id = Integer.parseInt(tokens[2]);
|
2022-09-12 23:01:23 -07:00
|
|
|
DbcPacket packet = findPacket(id);
|
2022-08-19 20:16:59 -07:00
|
|
|
Objects.requireNonNull(packet, "packet for " + id);
|
|
|
|
String originalName = tokens[3];
|
|
|
|
String niceName = merge(tokens, 4);
|
|
|
|
packet.replaceName(originalName, niceName);
|
|
|
|
|
2022-06-20 14:29:02 -07:00
|
|
|
|
|
|
|
} else if (line.startsWith("SG_")) {
|
2022-08-27 16:57:29 -07:00
|
|
|
DbcField field = DbcField.parseField(currentPacket, line);
|
2022-06-26 09:15:18 -07:00
|
|
|
if (debugEnabled)
|
|
|
|
System.out.println("Found " + field);
|
2022-09-12 23:26:02 -07:00
|
|
|
if (field != null)
|
|
|
|
currentPacket.add(field);
|
2022-06-20 14:29:02 -07:00
|
|
|
|
|
|
|
} else {
|
|
|
|
// skipping useless line
|
|
|
|
}
|
|
|
|
}
|
2022-08-19 20:16:59 -07:00
|
|
|
purgePacket(currentPacket);
|
2022-06-26 09:15:18 -07:00
|
|
|
|
|
|
|
System.out.println(getClass().getSimpleName() + ": Total " + packets.size() + " packets");
|
2022-06-20 14:29:02 -07:00
|
|
|
}
|
2022-06-22 00:19:09 -07:00
|
|
|
|
2022-08-19 20:16:59 -07:00
|
|
|
private static String merge(String[] tokens, int position) {
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
for (int i = position; i < tokens.length; i++) {
|
|
|
|
if (sb.length() > 0)
|
|
|
|
sb.append(" ");
|
|
|
|
sb.append(tokens[i]);
|
2022-06-22 00:19:09 -07:00
|
|
|
}
|
2022-08-19 20:16:59 -07:00
|
|
|
return sb.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void purgePacket(DbcPacket currentPacket) {
|
|
|
|
if (currentPacket != null)
|
|
|
|
packets.put(currentPacket.getId(), currentPacket);
|
|
|
|
}
|
|
|
|
|
2022-08-27 16:57:29 -07:00
|
|
|
public static String replaceSpecialWithSpaces(String line) {
|
2022-08-19 20:16:59 -07:00
|
|
|
line = line.replaceAll("[|+@(,)\\[\\]]", " ");
|
|
|
|
line = line.replaceAll(" +", " ");
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
public DbcPacket findPacket(int canId) {
|
|
|
|
return packets.get(canId);
|
2022-06-22 00:19:09 -07:00
|
|
|
}
|
2022-08-26 17:11:21 -07:00
|
|
|
|
|
|
|
|
|
|
|
public List<BinaryLogEntry> getFieldNameEntries() {
|
|
|
|
if (list == null) {
|
2022-09-12 23:01:23 -07:00
|
|
|
list = LoggingStrategy.getFieldNameEntries(this, logOnlyTranslatedFields);
|
2022-08-26 17:11:21 -07:00
|
|
|
}
|
|
|
|
return list;
|
|
|
|
}
|
2022-09-12 23:01:23 -07:00
|
|
|
|
|
|
|
public DbcPacket getPacketByIndexSlow(int index) {
|
|
|
|
return new ArrayList<>(packets.values()).get(index);
|
|
|
|
}
|
2022-06-20 14:29:02 -07:00
|
|
|
}
|