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 });