Merge branch 'dev'
diff --git a/build.gradle b/build.gradle
index 050b85b..c076045 100644
--- a/build.gradle
+++ b/build.gradle
@@ -8,7 +8,7 @@
description = 'MDF Sorter'
group = 'org.eclipse.mdm'
-version = '1.0.2'
+version = '1.0.3'
apply plugin: 'java'
apply plugin: 'eclipse'
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/MDFParser.java b/src/main/java/org/eclipse/mdm/mdfsorter/MDFParser.java
index 24f6450..999d61f 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/MDFParser.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/MDFParser.java
@@ -58,6 +58,13 @@
MDFSorter.log.severe("MDF Version " + String.valueOf(versionnum) + "is not supported. Aborting.");
throw new IllegalArgumentException("Unsupported MDF Version.");
} else if (version < 400) {
+ if (version == 330) {
+ int codePage = MDF4Util.readUInt16(getDataBuffer(idblock, 30, 32));
+ if (codePage != 0) {
+ MDFSorter.log.warning("code page is defined to be '" + codePage
+ + "' (value is ignored and ISO-8859-1 is used for string en-/decoding)");
+ }
+ }
boolean bigendian = MDF4Util.readUInt16(getDataBuffer(idblock, 24, 26)) != 0;
myParser = new MDF3Parser(in, bigendian);
} else {
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/MDFSorter.java b/src/main/java/org/eclipse/mdm/mdfsorter/MDFSorter.java
index 3e64cd5..66a228a 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/MDFSorter.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/MDFSorter.java
@@ -36,7 +36,7 @@
/**
* Version of this tool as String. (Used in the file Header)
*/
- public static final String VERSIONSTRING = "1.0.2";
+ public static final String VERSIONSTRING = "1.0.3";
/**
* The logger for this application
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/CCBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/CCBLOCK.java
index 46ad31e..f158a65 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/CCBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/CCBLOCK.java
@@ -215,7 +215,7 @@
setMaxPhysValue(MDF4Util.readReal(MDFParser.getDataBuffer(content, 10, 18)));
// CHAR 20 Physical unit
- setPhysUnit(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 18, 38), 20));
+ setPhysUnit(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 18, 38), 20));
// UINT16 1 Conversion formula identifier
// 0 = parametric, linear
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/CNBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/CNBLOCK.java
index a94c633..a04bbb0 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/CNBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/CNBLOCK.java
@@ -260,10 +260,10 @@
// CHAR 32 Signal name, i.e. the first 32 characters of the ASAM-MCD
// unique name
- setSignalName(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 2, 34), 32));
+ setSignalName(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 2, 34), 32));
// CHAR 128 Signal description
- setSignalDescription(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 34, 162), 128));
+ setSignalDescription(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 34, 162), 128));
// UINT16 1 Number of the first bits [0..n] (bit position within a byte:
// bit 0 is the least significant
@@ -315,9 +315,9 @@
b.put(MDF3Util.getBytesUInt16(getChannelType(), isBigEndian()));
- b.put(MDF4Util.getBytesCharsUTF8(getSignalName()));
+ b.put(MDF3Util.getBytesCharsISO8859(getSignalName()));
- b.put(MDF4Util.getBytesCharsUTF8(getSignalDescription()));
+ b.put(MDF3Util.getBytesCharsISO8859(getSignalDescription()));
b.put(MDF3Util.getBytesUInt16(getNumberOfFirstBits(), isBigEndian()));
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/HDBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/HDBLOCK.java
index af94ee5..66896d0 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/HDBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/HDBLOCK.java
@@ -12,7 +12,6 @@
import java.nio.ByteBuffer;
import org.eclipse.mdm.mdfsorter.MDFParser;
-import org.eclipse.mdm.mdfsorter.mdf4.MDF4Util;
/**
* The Data Group Block
@@ -199,16 +198,16 @@
setNumberOfDataGroups(MDF3Util.readUInt16(MDFParser.getDataBuffer(content, 0, 2), isBigEndian()));
// CHAR 10 Date when the recording was started
- setDateStarted(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 2, 12), 10));
+ setDateStarted(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 2, 12), 10));
// CHAR 8 Signal name, i.e. the first 32 characters of the ASAM-MCD
// unique name
- setTimeStarted(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 12, 20), 8));
+ setTimeStarted(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 12, 20), 8));
- setAuthor(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 20, 52), 32));
- setDepartment(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 52, 84), 32));
- setProjectName(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 84, 116), 32));
- setMeaObject(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 116, 148), 32));
+ setAuthor(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 20, 52), 32));
+ setDepartment(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 52, 84), 32));
+ setProjectName(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 84, 116), 32));
+ setMeaObject(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 116, 148), 32));
if (content.length > 148) {
// UNINT 64 Timestamp
@@ -225,7 +224,7 @@
}
if (content.length > 160) {
- setTimerIdent(MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(content, 160, 192), 32));
+ setTimerIdent(MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(content, 160, 192), 32));
}
}
@@ -238,17 +237,17 @@
b.put(MDF3Util.getBytesUInt16(getNumberOfDataGroups(), isBigEndian()));
- b.put(MDF4Util.getBytesCharsUTF8(getDateStarted()));
+ b.put(MDF3Util.getBytesCharsISO8859(getDateStarted()));
- b.put(MDF4Util.getBytesCharsUTF8(getTimeStarted()));
+ b.put(MDF3Util.getBytesCharsISO8859(getTimeStarted()));
- b.put(MDF4Util.getBytesCharsUTF8(getAuthor()));
+ b.put(MDF3Util.getBytesCharsISO8859(getAuthor()));
- b.put(MDF4Util.getBytesCharsUTF8(getDepartment()));
+ b.put(MDF3Util.getBytesCharsISO8859(getDepartment()));
- b.put(MDF4Util.getBytesCharsUTF8(getProjectName()));
+ b.put(MDF3Util.getBytesCharsISO8859(getProjectName()));
- b.put(MDF4Util.getBytesCharsUTF8(getMeaObject()));
+ b.put(MDF3Util.getBytesCharsISO8859(getMeaObject()));
if (arraylength > 148) {
b.put(MDF3Util.getBytesUInt64(getTimestamp(), isBigEndian()));
@@ -263,7 +262,7 @@
}
if (arraylength > 160) {
- b.put(MDF4Util.getBytesCharsUTF8(getTimerIdent()));
+ b.put(MDF3Util.getBytesCharsISO8859(getTimerIdent()));
}
return b.array();
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3Parser.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3Parser.java
index e9a5c16..0381b62 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3Parser.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3Parser.java
@@ -120,7 +120,7 @@
in.position(start.getPos());
byte[] head = readBytes(4, in);
// Read header of this block
- String blktyp = MDF4Util.readCharsUTF8(MDFParser.getDataBuffer(head, 0, 2), 2);
+ String blktyp = MDF3Util.readCharsISO8859(MDFParser.getDataBuffer(head, 0, 2), 2);
start.setId(blktyp);
int blklength = MDF4Util.readUInt16(MDFParser.getDataBuffer(head, 2, 4));
start.setLength(blklength);
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3ProcessWriter.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3ProcessWriter.java
index 19baab9..80f48f5 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3ProcessWriter.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3ProcessWriter.java
@@ -13,6 +13,7 @@
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
@@ -40,6 +41,8 @@
*/
public class MDF3ProcessWriter extends MDFAbstractProcessWriter<MDF3GenBlock> {
+ private MDF3GenBlock lastDGBlockParent;
+
/**
* Main Constructor.
*
@@ -74,6 +77,8 @@
for (MDF3GenBlock blk : filestructure.getList()) {
if (blk instanceof CGBLOCK) {
numberOfDatagroups++;
+ } else if(blk instanceof HDBLOCK) {
+ lastDGBlockParent = blk;
}
}
// Check if zip flag is not set
@@ -237,27 +242,46 @@
long[][] startaddresses = fillRecordArray(recCounters, recNumtoArrIdx, recNumtoSize, prov, redundantids);
- MDF3GenBlock last = (MDF3GenBlock) prob.getParentnode();
-
// write new blocks
for (CGBLOCK cgroup : groups) {
int arridx = recNumtoArrIdx.get(cgroup.getRecordId());
MDFSorter.log.fine("Writing data for Block " + arridx + ".");
long newlength;
+
+ long newCycleCount = newCycleCount(startaddresses[arridx]);
+ if (newCycleCount > -1) {
+ // missing records exist, update cycle count
+ // to match number of existing records
+ cgroup.setCycleCount(newCycleCount);
+ }
+
// create new datagroup
- last = copyChannelInfrastructure(last, cgroup);
+ lastDGBlockParent = copyChannelInfrastructure(lastDGBlockParent, cgroup);
long reclen = cgroup.getDataBytes();
newlength = cgroup.getCycleCount() * cgroup.getDataBytes();
- MDF3BlocksSplittMerger splitmerger = new MDF3BlocksSplittMerger(this, last, newlength, prov);
+ MDF3BlocksSplittMerger splitmerger = new MDF3BlocksSplittMerger(this, lastDGBlockParent, newlength, prov);
// write data sections.
for (long l : startaddresses[arridx]) {
+ if (l == -1L) {
+ // remaining records are missing => trim
+ break;
+ }
splitmerger.splitmerge(l + idSize, reclen);
}
splitmerger.setLinks();
}
}
+ private long newCycleCount(long[] addrs) {
+ for (int i = 0; i < addrs.length; i++) {
+ if (addrs[i] == -1L) {
+ return i;
+ }
+ }
+ return -1L;
+ }
+
public long[][] fillRecordArray(long[] recordCounters, Map<Integer, Integer> recNumtoArrIdx,
Map<Integer, Integer> recNumtoSize, AbstractDataProvider prov, boolean redundantids)
throws IOException, DataFormatException {
@@ -273,6 +297,7 @@
for (long i : recordCounters) {
totalRecords += i;
startaddresses[counter++] = new long[(int) i];
+ Arrays.fill(startaddresses[counter - 1], -1L);
}
int[] foundrecCounters = new int[recordCounters.length];
@@ -287,7 +312,12 @@
int foundID = MDF3Util.readUInt8(databuf);
Integer foundsize = recNumtoSize.get(foundID);
if (foundsize == null) { // Check if a size was found.
- throw new RuntimeException("No Size known for record ID " + foundID + ".");
+ if (foundID == 0) {
+ MDFSorter.log.info("Record ID '0' found => cutting off missing records,"
+ + " since those are not recoverable.");
+ return startaddresses;
+ }
+ throw new RuntimeException("Record ID '" + foundID + "' does not exist, file may be corrupt.");
}
if (redundantids) {
// do a sanity check with the second id
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3Util.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3Util.java
index 8f597a4..2ef61f2 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3Util.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf3/MDF3Util.java
@@ -8,6 +8,7 @@
package org.eclipse.mdm.mdfsorter.mdf3;
+import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
@@ -225,4 +226,26 @@
public static byte[] getBytesLink(long val, boolean bigendian) {
return getBytesUInt32(val, bigendian);
}
+
+ /**
+ * Read a String from ISO8859 encoded bytes
+ *
+ * @param bb
+ * The ByteBuffer to use.
+ * @param length
+ * Number of chars to read.
+ * @return The result as String.
+ * @throws IOException
+ * If an reading error occurs.
+ */
+ public static String readCharsISO8859(ByteBuffer bb, int length) throws IOException {
+ byte[] b = new byte[length];
+ bb.get(b);
+ return new String(b, 0, length, "ISO-8859-1");
+ }
+
+ public static byte[] getBytesCharsISO8859(String s) throws IOException {
+ return s.getBytes("ISO-8859-1");
+ }
+
}