now handling comments section

This commit is contained in:
rusefillc 2022-08-19 23:16:59 -04:00
parent e2951150d6
commit d0eae47a8e
5 changed files with 175 additions and 15 deletions

View File

@ -17,7 +17,7 @@ import java.util.concurrent.atomic.AtomicReference;
public class LoggingStrategy {
public static List<BinaryLogEntry> getFieldNameEntries(DbcFile dbc) {
List<BinaryLogEntry> entries = new ArrayList<>();
for (DbcPacket packet : dbc.packets) {
for (DbcPacket packet : dbc.packets.values()) {
for (DbcField field : packet.getFields()) {
entries.add(new BinaryLogEntry() {
@Override

View File

@ -3,11 +3,12 @@ package com.rusefi.can.reader.dbc;
import com.rusefi.can.CANPacket;
public class DbcField {
private final String name;
private String name;
private final int startOffset;
private final int length;
private final double mult;
private String category;
private boolean isNiceName;
public DbcField(String name, int startOffset, int length, double mult, String category) {
this.name = name;
@ -21,6 +22,10 @@ public class DbcField {
return category;
}
public boolean isNiceName() {
return isNiceName;
}
public String getName() {
return name;
}
@ -67,4 +72,9 @@ public class DbcField {
public double getValue(CANPacket packet) {
return getBitIndex(packet.getData(), startOffset, length) * mult;
}
public void rename(String niceName) {
name = niceName;
isNiceName = true;
}
}

View File

@ -4,10 +4,12 @@ import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
public class DbcFile {
public final List<DbcPacket> packets = new ArrayList<>();
public final LinkedHashMap<Integer, DbcPacket> packets = new LinkedHashMap<>();
private static final boolean debugEnabled = false;
@ -26,17 +28,26 @@ public class DbcFile {
while ((line = reader.readLine()) != null) {
line = line.trim();
if (line.startsWith("BO_")) {
if (currentPacket != null)
this.packets.add(currentPacket);
purgePacket(currentPacket);
line = line.replaceAll(":", "");
String[] tokens = line.split(" ");
int decId = Integer.parseInt(tokens[1]);
String packetName = tokens[2];
currentPacket = new DbcPacket(decId, packetName);
} else if (line.startsWith("CM_")) {
purgePacket(currentPacket);
line = replaceSpecialWithSpaces(line);
String[] tokens = line.split(" ");
int id = Integer.parseInt(tokens[2]);
DbcPacket packet = packets.get(id);
Objects.requireNonNull(packet, "packet for " + id);
String originalName = tokens[3];
String niceName = merge(tokens, 4);
packet.replaceName(originalName, niceName);
} else if (line.startsWith("SG_")) {
line = line.replaceAll("[|+@(,)\\[\\]]", " ");
line = line.replaceAll(" +", " ");
line = replaceSpecialWithSpaces(line);
String[] tokens = line.split(" ");
String name = tokens[1];
int index = 1;
@ -65,18 +76,33 @@ public class DbcFile {
// skipping useless line
}
}
if (currentPacket != null)
this.packets.add(currentPacket);
purgePacket(currentPacket);
System.out.println(getClass().getSimpleName() + ": Total " + packets.size() + " packets");
}
// todo: performance optimization SOON
public DbcPacket findPacket(int i) {
for (DbcPacket packet : packets) {
if (packet.getId() == i)
return packet;
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]);
}
return null;
return sb.toString();
}
private void purgePacket(DbcPacket currentPacket) {
if (currentPacket != null)
packets.put(currentPacket.getId(), currentPacket);
}
private String replaceSpecialWithSpaces(String line) {
line = line.replaceAll("[|+@(,)\\[\\]]", " ");
line = line.replaceAll(" +", " ");
return line;
}
public DbcPacket findPacket(int canId) {
return packets.get(canId);
}
}

View File

@ -1,8 +1,13 @@
package com.rusefi.can.reader.dbc;
import javax.management.ObjectName;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* Packet describes all the fields for specific can ID
*/
public class DbcPacket {
private final int id;
private final String name;
@ -44,4 +49,54 @@ public class DbcPacket {
}
return null;
}
public void replaceName(String originalName, String niceName) {
if (niceName.charAt(niceName.length() - 1) == ';')
niceName = niceName.substring(0, niceName.length() - 1);
niceName = unquote(niceName);
DbcField field = find(originalName);
Objects.requireNonNull(field, "By " + originalName);
field.rename(niceName);
}
private static String unquote(String q) {
final StringBuilder buf = new StringBuilder();
final int len = q.length();
if (len < 2 || q.charAt(0) != '"' || q.charAt(len - 1) != '"')
return q;
for (int i = 1; i < len - 1; i++) {
char c = q.charAt(i);
if (c == '\\') {
if (i == len - 2)
throw new IllegalArgumentException("Trailing backslash");
c = q.charAt(++i);
switch (c) {
case 'n':
c = '\n';
break;
case '\\':
case '\"':
case '*':
case '?':
break;
default:
throw new IllegalArgumentException(
"Bad character '" + c + "' after backslash");
}
} else {
switch (c) {
case '*':
case '?':
case '\"':
case '\n':
throw new IllegalArgumentException(
"Invalid unescaped character '" + c +
"' in the string to unquote");
}
}
buf.append(c);
}
return buf.toString();
}
}

View File

@ -0,0 +1,69 @@
package com.rusefi.can.reader.impl;
import com.rusefi.can.reader.dbc.DbcField;
import com.rusefi.can.reader.dbc.DbcFile;
import com.rusefi.can.reader.dbc.DbcPacket;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import static junit.framework.TestCase.*;
public class ParseDBCWithCommentTest {
private static final String RPM_DBC =
"\n" +
"BO_ 1408 Motor_Flexia: 8 XXX\n" +
" SG_ Ansaugsystem m0 : 63|1@1+ (1,0) [0|0] \"\" XXX\n" +
" SG_ Hubraum m0 : 56|7@1+ (0.1,0) [0|12.7] \"l\" XXX\n" +
" SG_ Steigung_der_Befuellungskennlin m1 : 56|8@1+ (0.001,0) [0|0.255] \"l/mm\" XXX\n" +
" SG_ Anzahl_Zylinder m0 : 52|4@1+ (1,0) [0|15] \"Vent./Zyl.\" XXX\n" +
" SG_ Bewertungsfaktor_Russindex_Turb m1 : 50|6@1+ (0.1,0) [0|6.3] \"\" XXX\n" +
" SG_ Anzahl_Ventile m0 : 49|3@1+ (1,0) [0|7] \"Vent./Zyl.\" XXX\n" +
" SG_ Bewertungsfaktor_Verschleissind m1 : 44|6@1+ (0.1,0) [0|6.3] \"\" XXX\n" +
" SG_ Hersteller_Code m1 : 40|4@1+ (1,0) [0|15] \"\" XXX\n" +
" SG_ Motorleistung m0 : 40|9@1+ (1,0) [0|512] \"KW\" XXX\n" +
" SG_ Max_Drehmoment m0 : 32|8@1+ (10,0) [0|2550] \"Nm\" XXX\n" +
" SG_ Normierter_Verbrauch m1 : 32|8@1+ (10,0) [0|2550] \"l/Zyl.\" XXX\n" +
" SG_ Oelniveauschwelle m1 : 24|8@1+ (0.25,0) [0|63.75] \"cm\" XXX\n" +
" SG_ Drehzahl_MaxNorm m0 : 24|8@1+ (100,0) [0|25500] \"U/min\" XXX\n" +
" SG_ Verschleissindex : 16|8@1+ (1,0) [0|254] \"\" XXX\n" +
" SG_ Russindex : 8|8@1+ (1,0) [0|254] \"\" XXX\n" +
" SG_ Verbrennungsart : 7|1@1+ (1,0) [0|0] \"\" XXX\n" +
" SG_ Frei_Motor_Flexia_1 : 6|1@1+ (1,0) [0|0] \"\" XXX\n" +
" SG_ Warm_Up_Cycle : 5|1@1+ (1,0) [0|0] \"\" XXX\n" +
" SG_ Driving_Cycle : 4|1@1+ (1,0) [0|0] \"\" XXX\n" +
" SG_ Zaehler_Motor_Flexia : 1|3@1+ (1,0) [0|15] \"\" XXX\n" +
" SG_ Multiplex_Schalter_Motor_Flexia M : 0|1@1+ (1,0) [0|0] \"\" XXX\n" +
"" +
"" +
"" +
"\n" +
"\n" +
"CM_ SG_ 1408 Zaehler_Motor_Flexia \"Counter Motor_Flexia\";\n" +
"CM_ SG_ 1408 Verbrennungsart \"Type of combustion\";\n" +
"CM_ SG_ 1408 Max_Drehmoment \"Maximum torque\";\n" +
"CM_ SG_ 1408 Drehzahl_MaxNorm \"RPM of maximum torque\";\n" +
"CM_ SG_ 1408 Hubraum \"Displacement\";\n" +
"CM_ SG_ 1408 Anzahl_Zylinder \"Number of cylinders\";\n" +
"CM_ SG_ 1408 Anzahl_Ventile \"Number of valves\";\n" +
"CM_ SG_ 1408 Ansaugsystem \"Induction System\";\n" +
"CM_ SG_ 1408 Motorleistung \"Maximum engine power\";\n" +
"";
@Test
public void parse() throws IOException {
BufferedReader reader = new BufferedReader(new StringReader(RPM_DBC));
DbcFile dbc = new DbcFile();
dbc.read(reader);
assertEquals(dbc.packets.size(), 1);
DbcPacket packet = dbc.packets.get(1408);
DbcField field = packet.find("Number of cylinders");
assertNotNull(field);
assertTrue(field.isNiceName());
}
}