Fixed NPE in MDF4ProcessWriter#fillRecordArray
NPE is caused by wrongly reading an UINT8 as INT8. The error is in
MDF4Util#readUInt8 which is called by multiple other locations in the
code. Fixing the method required changing the return type, which led to
changes in various *BLOCKs.
Change-Id: I62754f19e940d08143c57230b787c219f72ab3e8
Signed-off-by: Matthias Koller <m.koller@peak-solution.de>
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/CCBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/CCBLOCK.java
index f51a798..edaa1d9 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/CCBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/CCBLOCK.java
@@ -48,7 +48,7 @@
// 9 = text to value tabular look-up
// 10 = text to text tabular look-up (translation)
// UINT8
- private byte type;
+ private int type;
// Precision for display of floating point values.
// 0xFF means unrestricted precision (infinite)
@@ -58,7 +58,7 @@
// cn_precision of the parent CNBLOCK is invalid,
// otherwise cn_precision must be used.
// UINT8
- private byte precision;
+ private int precision;
// Flags
// The value contains the following bit flags (Bit 0 = LSB):
@@ -138,11 +138,11 @@
return ret;
}
- public byte getType() {
+ public int getType() {
return type;
}
- public byte getPrecision() {
+ public int getPrecision() {
return precision;
}
@@ -170,11 +170,11 @@
return val;
}
- private void setType(byte type) {
+ private void setType(int type) {
this.type = type;
}
- private void setPrecision(byte precision) {
+ private void setPrecision(int precision) {
this.precision = precision;
}
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/CHBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/CHBLOCK.java
index e4ef657..d91b6ac 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/CHBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/CHBLOCK.java
@@ -59,7 +59,7 @@
/**
* Type of the hierachy this CHBLOCK maintaines.
*/
- private byte hirarchyType;
+ private int hirarchyType;
// Getters and Setters
// Link to next CHBLOCK
@@ -101,11 +101,11 @@
this.elementCount = elementCount;
}
- public byte getHirarchyType() {
+ public int getHirarchyType() {
return hirarchyType;
}
- public void setHirarchyType(byte hirarchyType) {
+ public void setHirarchyType(int hirarchyType) {
this.hirarchyType = hirarchyType;
}
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DGBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DGBLOCK.java
index 8964aec..58ff9d6 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DGBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DGBLOCK.java
@@ -36,7 +36,7 @@
// 4 = record ID (UINT32, LE Byte order) before each data record
// 8 = record ID (UINT64, LE Byte order) before each data record
// UINT8
- private byte recIdSize;
+ private int recIdSize;
/**
* Parse a HLBLOCK from an existing MDFGenBlock
@@ -78,11 +78,11 @@
return links[3];
}
- public byte getRecIdSize() {
+ public int getRecIdSize() {
return recIdSize;
}
- public void setRecIdSize(byte recIdSize) {
+ public void setRecIdSize(int recIdSize) {
this.recIdSize = recIdSize;
}
@@ -112,7 +112,7 @@
public byte[] getBodyBytes() {
// UINT8: Number of Bytes used for record IDs in the data block.
byte[] ret = new byte[8];
- ret[0] = getRecIdSize();
+ ret[0] = MDF4Util.toUInt8(getRecIdSize());
return ret;
}
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DLBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DLBLOCK.java
index dc6d0f3..b2b01bc 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DLBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DLBLOCK.java
@@ -40,7 +40,7 @@
// Flags
// Bit 0: Equal length flag
// UINT8
- private byte flags;
+ private int flags;
// Number of referenced blocks N
// UINT32
@@ -84,7 +84,7 @@
return Arrays.copyOfRange(links, 1, links.length);
}
- public byte getFlags() {
+ public int getFlags() {
return flags;
}
@@ -100,7 +100,7 @@
return offset;
}
- public void setFlags(byte flags) {
+ public void setFlags(int flags) {
this.flags = flags;
}
@@ -162,7 +162,7 @@
byte[] ret = new byte[arraylen];
// flags UINT8
- ret[0] = flags;
+ ret[0] = MDF4Util.toUInt8(flags);
byte[] count = MDF4Util.getBytesUInt32(this.count);
System.arraycopy(count, 0, ret, 4, 4);
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DZBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DZBLOCK.java
index 3812268..c2034de 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DZBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/DZBLOCK.java
@@ -37,7 +37,7 @@
// Zip algorithm used to compress the data (0=Deflate; 1=Transpose and
// Deflate)
// UINT8
- private byte zip_type;
+ private int zip_type;
// Parameters for zip algorithm
// UINT32
@@ -82,11 +82,11 @@
this.block_type = block_type;
}
- public byte getZip_type() {
+ public int getZip_type() {
return zip_type;
}
- public void setZip_type(byte zip_type) {
+ public void setZip_type(int zip_type) {
this.zip_type = zip_type;
}
@@ -146,7 +146,7 @@
byte[] type = MDF4Util.getBytesCharsUTF8(getBlock_type());
System.arraycopy(type, 0, ret, 0, 2);
- ret[3] = zip_type;
+ ret[3] = MDF4Util.toUInt8(zip_type);
byte[] zipparam = MDF4Util.getBytesUInt32(zip_parameters);
System.arraycopy(zipparam, 0, ret, 4, 4);
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/FHBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/FHBLOCK.java
index 20b8d28..c9276fc 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/FHBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/FHBLOCK.java
@@ -42,7 +42,7 @@
// Time flags Bit 0: Local Time flag / Bit 1: Time offset valid flag
// UINT8
- private byte time_flags;
+ private int time_flags;
/**
* Constructor
@@ -93,11 +93,11 @@
this.dst_offset_min = dst_offset_min;
}
- public byte getTime_flags() {
+ public int getTime_flags() {
return time_flags;
}
- public void setTime_flags(byte time_flags) {
+ public void setTime_flags(int time_flags) {
this.time_flags = time_flags;
}
@@ -124,7 +124,7 @@
byte[] dst_offset = MDF4Util.getBytesInt16(getDst_offset_min());
System.arraycopy(dst_offset, 0, ret, 10, 2);
- ret[11] = time_flags;
+ ret[11] = MDF4Util.toUInt8(time_flags);
return ret;
}
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/HDBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/HDBLOCK.java
index 136dddb..4f8e70b 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/HDBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/HDBLOCK.java
@@ -75,14 +75,14 @@
// (after conversion of offsets to ns) by
// Local time = UTC time + time zone offset + DST offset.
// UINT8
- private byte timeFlags;
+ private int timeFlags;
// Time quality class
// 0 = local PC reference time (Default)
// 10 = external time source
// 16 = external absolute synchronized time
// UINT8
- private byte timeClass;
+ private int timeClass;
// Flags
// The value contains the following bit flags (Bit 0 = LSB):
@@ -91,7 +91,7 @@
// Bit 1: Start distance valid flag. If set, the start distance value below
// is valid.
// UINT8
- private byte flags;
+ private int flags;
// Start angle in radians at start of measurement (only for angle
// synchronous measurements)
@@ -169,27 +169,27 @@
this.dstOffsetMin = dstOffsetMin;
}
- public byte getTimeFlags() {
+ public int getTimeFlags() {
return timeFlags;
}
- private void setTimeFlags(byte timeFlags) {
+ private void setTimeFlags(int timeFlags) {
this.timeFlags = timeFlags;
}
- public byte getTimeClass() {
+ public int getTimeClass() {
return timeClass;
}
- private void setTimeClass(byte timeClass) {
+ private void setTimeClass(int timeClass) {
this.timeClass = timeClass;
}
- public byte getFlags() {
+ public int getFlags() {
return flags;
}
- private void setFlags(byte flags) {
+ private void setFlags(int flags) {
this.flags = flags;
}
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/HLBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/HLBLOCK.java
index 3338407..9635124 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/HLBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/HLBLOCK.java
@@ -38,7 +38,7 @@
// Zip algorithm used to compress the data (0=Deflate; 1=Transpose and
// Deflate)
// UINT8
- private byte ziptype;
+ private int ziptype;
public HLBLOCK() {
super(0);
@@ -70,11 +70,11 @@
this.flags = flags;
}
- public byte getZiptype() {
+ public int getZiptype() {
return ziptype;
}
- public void setZiptype(byte ziptype) {
+ public void setZiptype(int ziptype) {
this.ziptype = ziptype;
}
@@ -101,7 +101,7 @@
byte[] hl_flags = MDF4Util.getBytesUInt16(flags);
System.arraycopy(hl_flags, 0, ret, 0, 2);
- ret[3] = ziptype;
+ ret[3] = MDF4Util.toUInt8(ziptype);
return ret;
}
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/MDF4ProcessWriter.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/MDF4ProcessWriter.java
index 08131a5..c6668ea 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/MDF4ProcessWriter.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/MDF4ProcessWriter.java
@@ -437,7 +437,7 @@
int[] recCounters = new int[groups.size()];
- byte idSize = datagroup.getRecIdSize();
+ int idSize = datagroup.getRecIdSize();
int i = 0;
Map<Long, Integer> recNumtoArrIdx = new HashMap<Long, Integer>();
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/MDF4Util.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/MDF4Util.java
index 6618302..bad025e 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/MDF4Util.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/MDF4Util.java
@@ -47,21 +47,36 @@
* The byte buffer.
* @return The value.
*/
- public static byte readUInt8(ByteBuffer bb) {
+ public static byte readInt8(ByteBuffer bb) {
return bb.order(ByteOrder.LITTLE_ENDIAN).get();
}
/**
- * Read an 8-bit signed integer from the byte buffer.
+ * Read an 8-bit unsigned integer from the byte buffer.
*
* @param bb
* The byte buffer.
* @return The value.
*/
- public static int readInt8(ByteBuffer bb) {
+ public static int readUInt8(ByteBuffer bb) {
return bb.order(ByteOrder.LITTLE_ENDIAN).get() & 0xff;
}
+ /**
+ * Convert an integer to a UINT8 byte
+ *
+ * @param uint value as int
+ * @return byte representing the uint8
+ * @throws IllegalArgumentException if the value is out of range [0, 255]
+ */
+ public static byte toUInt8(int uint) {
+ if (uint >= 0 && uint < 256) {
+ return (byte) (uint & 0xff);
+ } else {
+ throw new IllegalArgumentException(uint + " cannot be converted to UINT8.");
+ }
+ }
+
/**
* Read an 16-bit unsigned integer from the byte buffer.
*
diff --git a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/SIBLOCK.java b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/SIBLOCK.java
index 3106210..73502fc 100644
--- a/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/SIBLOCK.java
+++ b/src/main/java/org/eclipse/mdm/mdfsorter/mdf4/SIBLOCK.java
@@ -42,7 +42,7 @@
// 5 = USER source is a user interaction/input
// (e.g. for user generated events)
// UINT8
- private byte sourceType;
+ private int sourceType;
// Bus type: additional classification of used bus (should be 0 for si_type
// ≥ 3):
@@ -57,7 +57,7 @@
// 8 = USB
// Vender defined bus types can be added starting with value 128.
// UINT8
- private byte busType;
+ private int busType;
// Flags
// The value contains the following bit flags (Bit 0 = LSB):
@@ -65,7 +65,7 @@
// Source is only a simulation (can be hardware or software simulated)
// Cannot be set for si_type = 4 (TOOL).
// UINT8
- private byte flags;
+ private int flags;
/**
* Parse a SIBLOCK from an existing MDFGenBlock
@@ -82,15 +82,15 @@
parent.setPrec(this);
}
- private void setSourceType(byte sourceType) {
+ private void setSourceType(int sourceType) {
this.sourceType = sourceType;
}
- private void setBusType(byte busType) {
+ private void setBusType(int busType) {
this.busType = busType;
}
- private void setFlags(byte flags) {
+ private void setFlags(int flags) {
this.flags = flags;
}
@@ -106,15 +106,15 @@
return links[2];
}
- public byte getSourceType() {
+ public int getSourceType() {
return sourceType;
}
- public byte getBusType() {
+ public int getBusType() {
return busType;
}
- public byte getFlags() {
+ public int getFlags() {
return flags;
}
diff --git a/src/test/java/org/eclipse/mdm/mdfsorter/MDF4UtilTest.java b/src/test/java/org/eclipse/mdm/mdfsorter/MDF4UtilTest.java
index f4fdbee..4748c0b 100644
--- a/src/test/java/org/eclipse/mdm/mdfsorter/MDF4UtilTest.java
+++ b/src/test/java/org/eclipse/mdm/mdfsorter/MDF4UtilTest.java
@@ -16,6 +16,10 @@
package org.eclipse.mdm.mdfsorter;
import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.nio.ByteBuffer;
import org.eclipse.mdm.mdfsorter.mdf4.MDF4Util;
import org.junit.AfterClass;
@@ -33,6 +37,51 @@
}
@Test
+ public void testReadUInt8() {
+ ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 1, 127, -128, -1 });
+
+ assertEquals(MDF4Util.readUInt8(bb), 0);
+ assertEquals(MDF4Util.readUInt8(bb), 1);
+ assertEquals(MDF4Util.readUInt8(bb), 127);
+ assertEquals(MDF4Util.readUInt8(bb), 128);
+ assertEquals(MDF4Util.readUInt8(bb), 255);
+ }
+
+ @Test
+ public void testToUInt8() {
+ assertEquals(MDF4Util.toUInt8(0), 0);
+ assertEquals(MDF4Util.toUInt8(1), 1);
+ assertEquals(MDF4Util.toUInt8(127), 127);
+ assertEquals(MDF4Util.toUInt8(128), -128);
+ assertEquals(MDF4Util.toUInt8(255), -1);
+
+ try {
+ MDF4Util.toUInt8(256);
+ fail("Should throw an exception!");
+ } catch (IllegalArgumentException e) {
+ assertEquals(e.getMessage(), "256 cannot be converted to UINT8.");
+ }
+
+ try {
+ MDF4Util.toUInt8(-1);
+ fail("Should throw an exception!");
+ } catch (IllegalArgumentException e) {
+ assertEquals(e.getMessage(), "-1 cannot be converted to UINT8.");
+ }
+ }
+
+ @Test
+ public void testReadInt8() {
+ ByteBuffer bb = ByteBuffer.wrap(new byte[] { 0, 1, 127, -128, -1 });
+
+ assertEquals(MDF4Util.readInt8(bb), 0);
+ assertEquals(MDF4Util.readInt8(bb), 1);
+ assertEquals(MDF4Util.readInt8(bb), 127);
+ assertEquals(MDF4Util.readInt8(bb), -128);
+ assertEquals(MDF4Util.readInt8(bb), -1);
+ }
+
+ @Test
public void testGetBytesUInt32() {
long l = Integer.MAX_VALUE * 2L + 1L;
assertArrayEquals(MDF4Util.getBytesUInt32(l), new byte[] { -1, -1, -1, -1 });