MessageParser { private static Data<?> parseData(byte[] data, int offset) throws SecsParseException { if (data.length < 2) { throw new SecsParseException("Invalid data length: " + data.length); } int formatByte = data[offset]; int formatCode = formatByte & 0xfc; int noOfLengthBytes = formatByte & 0x03; if (noOfLengthBytes < 1 || noOfLengthBytes > LENGTH_LENGTH) { throw new SecsParseException("Invalid number of length bytes: " + noOfLengthBytes); } if (data.length < noOfLengthBytes + 1) { throw new SecsParseException("Incomplete message data"); } int length = data[offset + 1]; if (noOfLengthBytes > 1) { length |= (data[offset + 2] << 8); } if (noOfLengthBytes > 2) { length |= (data[offset + 3] << 16); } if (noOfLengthBytes > 3) { length |= (data[offset + 4] << 24); } if (data.length < offset + 2 + length) { throw new SecsParseException("Incomplete message data"); } Data<?> dataItem = null; offset += (1 + noOfLengthBytes); switch (formatCode) { case L.FORMAT_CODE: dataItem = parseL(data, offset, length); break; case BOOLEAN.FORMAT_CODE: dataItem = parseBoolean(data, offset, length); break; case B.FORMAT_CODE: dataItem = parseB(data, offset, length); break; case A.FORMAT_CODE: dataItem = parseA(data, offset, length); break; case I1.FORMAT_CODE: dataItem = parseI1(data, offset, length); break; case I2.FORMAT_CODE: dataItem = parseI2(data, offset, length); break; case I4.FORMAT_CODE: dataItem = parseI4(data, offset, length); break; case I8.FORMAT_CODE: dataItem = parseI8(data, offset, length); break; case U1.FORMAT_CODE: dataItem = parseU1(data, offset, length); break; case U2.FORMAT_CODE: dataItem = parseU2(data, offset, length); break; case U4.FORMAT_CODE: dataItem = parseU4(data, offset, length); break; case U8.FORMAT_CODE: dataItem = parseU8(data, offset, length); break; case F4.FORMAT_CODE: dataItem = parseF4(data, offset, length); break; case F8.FORMAT_CODE: dataItem = parseF8(data, offset, length); break; default: throw new IllegalArgumentException(String.format("Invalid format code in message data: %02x", formatCode)); } return dataItem; }  static Message parseMessage(byte[] data, int length, Map<Integer, Class<? extends SecsMessage>> messageTypes); static Data<?> parseData(String text);  }
@Test public void dataI1() throws SecsException { Data<?> data = MessageParser.parseData("<I1>"); Assert.assertTrue(data instanceof I1); I1 i1 = (I1) data; Assert.assertEquals(0, i1.length()); data = MessageParser.parseData("<I1 -128 -1 0 1 127>"); Assert.assertTrue(data instanceof I1); i1 = (I1) data; Assert.assertEquals(5, i1.length()); Assert.assertEquals(-128, i1.getValue(0)); Assert.assertEquals(-1, i1.getValue(1)); Assert.assertEquals(0, i1.getValue(2)); Assert.assertEquals(1, i1.getValue(3)); Assert.assertEquals(127, i1.getValue(4)); }
@Test public void dataI2() throws SecsException { Data<?> data = MessageParser.parseData("<I2>"); Assert.assertTrue(data instanceof I2); I2 i2 = (I2) data; Assert.assertEquals(0, i2.length()); data = MessageParser.parseData("<I2 -32768 -1 0 1 32767>"); Assert.assertTrue(data instanceof I2); i2 = (I2) data; Assert.assertEquals(5, i2.length()); Assert.assertEquals(-32768, i2.getValue(0)); Assert.assertEquals(-1, i2.getValue(1)); Assert.assertEquals(0, i2.getValue(2)); Assert.assertEquals(1, i2.getValue(3)); Assert.assertEquals(32767, i2.getValue(4)); }
@Test public void dataI4() throws SecsException { Data<?> data = MessageParser.parseData("<I4>"); Assert.assertTrue(data instanceof I4); I4 i4 = (I4) data; Assert.assertEquals(0, i4.length()); data = MessageParser.parseData("<I4 -2147483647 -1 0 1 2147483646>"); Assert.assertTrue(data instanceof I4); i4 = (I4) data; Assert.assertEquals(5, i4.length()); Assert.assertEquals(-2147483647, i4.getValue(0)); Assert.assertEquals(-1, i4.getValue(1)); Assert.assertEquals(0, i4.getValue(2)); Assert.assertEquals(1, i4.getValue(3)); Assert.assertEquals(2147483646, i4.getValue(4)); }
@Test public void dataI8() throws SecsException { Data<?> data = MessageParser.parseData("<I8>"); Assert.assertTrue(data instanceof I8); I8 i8 = (I8) data; Assert.assertEquals(0, i8.length()); data = MessageParser.parseData("<I8 -65536 -1 0 1 65535>"); Assert.assertTrue(data instanceof I8); i8 = (I8) data; Assert.assertEquals(5, i8.length()); Assert.assertEquals(-65536, i8.getValue(0)); Assert.assertEquals(-1, i8.getValue(1)); Assert.assertEquals(0, i8.getValue(2)); Assert.assertEquals(1, i8.getValue(3)); Assert.assertEquals(65535, i8.getValue(4)); }
@Test public void dataF4() throws SecsException { Data<?> data = MessageParser.parseData("<F4>"); Assert.assertTrue(data instanceof F4); F4 f4 = (F4) data; Assert.assertEquals(0, f4.length()); data = MessageParser.parseData("<F4 -123.456 -1.0 0 1.0 123.456>"); Assert.assertTrue(data instanceof F4); f4 = (F4) data; Assert.assertEquals(5, f4.length()); Assert.assertEquals(-123.456f, f4.getValue(0), FLOAT_DELTA); Assert.assertEquals(-1.0f, f4.getValue(1), FLOAT_DELTA); Assert.assertEquals(0.0f, f4.getValue(2), FLOAT_DELTA); Assert.assertEquals(1.0f, f4.getValue(3), FLOAT_DELTA); Assert.assertEquals(123.456f, f4.getValue(4), FLOAT_DELTA); }
@Test public void dataF8() throws SecsException { Data<?> data = MessageParser.parseData("<F8>"); Assert.assertTrue(data instanceof F8); F8 f8 = (F8) data; Assert.assertEquals(0, f8.length()); data = MessageParser.parseData("<F8 -123.456 -1.0 0 1.0 123.456>"); Assert.assertTrue(data instanceof F8); f8 = (F8) data; Assert.assertEquals(5, f8.length()); Assert.assertEquals(-123.456, f8.getValue(0), FLOAT_DELTA); Assert.assertEquals(-1.0, f8.getValue(1), FLOAT_DELTA); Assert.assertEquals(0.0, f8.getValue(2), FLOAT_DELTA); Assert.assertEquals(1.0, f8.getValue(3), FLOAT_DELTA); Assert.assertEquals(123.456, f8.getValue(4), FLOAT_DELTA); }
@Test public void dataL() throws SecsException { Data<?> data = MessageParser.parseData("<L>"); Assert.assertTrue(data instanceof L); L l = (L) data; Assert.assertEquals(0, l.length()); data = MessageParser.parseData("<L <A \"V1\">>"); Assert.assertTrue(data instanceof L); l = (L) data; Assert.assertEquals(1, l.length()); Assert.assertTrue(l.getItem(0) instanceof A); A a = (A) l.getItem(0); Assert.assertEquals("V1", a.getValue()); data = MessageParser.parseData("<L <A \"V1\"> <A \"V2\">>"); Assert.assertTrue(data instanceof L); l = (L) data; Assert.assertEquals(2, l.length()); Assert.assertEquals("V1", l.getItem(0).getValue()); Assert.assertEquals("V2", l.getItem(1).getValue()); data = MessageParser.parseData("<L <L <A \"V1\"> <A \"V2\">> <L <A \"V3\"> <A \"V4\">>>"); Assert.assertTrue(data instanceof L); l = (L) data; Assert.assertEquals(2, l.length()); L l1 = (L) l.getItem(0); Assert.assertEquals("V1", l1.getItem(0).getValue()); Assert.assertEquals("V2", l1.getItem(1).getValue()); L l2 = (L) l.getItem(1); Assert.assertEquals(2, l2.length()); Assert.assertEquals("V3", l2.getItem(0).getValue()); Assert.assertEquals("V4", l2.getItem(1).getValue()); }
@Test public void emptyData() { try { MessageParser.parseData(null); Assert.fail("Missed exception"); } catch (SecsParseException e) { Assert.assertEquals("Empty data item", e.getMessage()); } try { MessageParser.parseData(""); Assert.fail("Missed exception"); } catch (SecsParseException e) { Assert.assertEquals("Empty data item or invalid length", e.getMessage()); } try { MessageParser.parseData(" "); Assert.fail("Missed exception"); } catch (SecsParseException e) { Assert.assertEquals("Empty data item or invalid length", e.getMessage()); } try { MessageParser.parseData("<>"); Assert.fail("Missed exception"); } catch (SecsParseException e) { Assert.assertEquals("Empty data item or invalid length", e.getMessage()); } }
@Test public void dataB() throws SecsException { Data<?> data = MessageParser.parseData("<B 0x01 0x02 0x03>"); Assert.assertTrue(data instanceof B); B b = (B) data; Assert.assertEquals(3, b.length()); Assert.assertEquals(0x01, b.get(0)); Assert.assertEquals(0x02, b.get(1)); Assert.assertEquals(0x03, b.get(2)); }
@Test public void dataBOOLEAN() throws SecsException { Data<?> data = MessageParser.parseData("<BOOLEAN True>"); Assert.assertTrue(data instanceof BOOLEAN); BOOLEAN b = (BOOLEAN) data; Assert.assertTrue(b.getValue()); data = MessageParser.parseData("<BOOLEAN False>"); Assert.assertTrue(data instanceof BOOLEAN); b = (BOOLEAN) data; Assert.assertFalse(b.getValue()); }
@Test public void dataA() throws SecsException { Data<?> data = MessageParser.parseData("<A>"); Assert.assertTrue(data instanceof A); A a = (A) data; Assert.assertEquals(0, a.length()); Assert.assertEquals("", a.getValue()); data = MessageParser.parseData("<A \"Test\">"); Assert.assertTrue(data instanceof A); a = (A) data; Assert.assertEquals(4, a.length()); Assert.assertEquals("Test", a.getValue()); }
@Test public void dataU1() throws SecsException { Data<?> data = MessageParser.parseData("<U1>"); Assert.assertTrue(data instanceof U1); U1 u1 = (U1) data; Assert.assertEquals(0, u1.length()); data = MessageParser.parseData("<U1 0 1 255>"); Assert.assertTrue(data instanceof U1); u1 = (U1) data; Assert.assertEquals(3, u1.length()); Assert.assertEquals(0x00, u1.getValue(0)); Assert.assertEquals(0x01, u1.getValue(1)); Assert.assertEquals(0xff, u1.getValue(2)); }
@Test public void dataU2() throws SecsException { Data<?> data = MessageParser.parseData("<U2>"); Assert.assertTrue(data instanceof U2); U2 u2 = (U2) data; Assert.assertEquals(0, u2.length()); data = MessageParser.parseData("<U2 0 1 65535>"); Assert.assertTrue(data instanceof U2); u2 = (U2) data; Assert.assertEquals(3, u2.length()); Assert.assertEquals(0x0000, u2.getValue(0)); Assert.assertEquals(0x0001, u2.getValue(1)); Assert.assertEquals(0xffff, u2.getValue(2)); }
@Test public void dataU4() throws SecsException { Data<?> data = MessageParser.parseData("<U4>"); Assert.assertTrue(data instanceof U4); U4 u4 = (U4) data; Assert.assertEquals(0, u4.length()); data = MessageParser.parseData("<U4 0 1 4294967295>"); Assert.assertTrue(data instanceof U4); u4 = (U4) data; Assert.assertEquals(0x00000000L, u4.getValue(0)); Assert.assertEquals(0x00000001L, u4.getValue(1)); Assert.assertEquals(0xffffffffL, u4.getValue(2)); }
@Test public void dataU8() throws SecsException { Data<?> data = MessageParser.parseData("<U8>"); Assert.assertTrue(data instanceof U8); U8 u8 = (U8) data; Assert.assertEquals(0, u8.length()); data = MessageParser.parseData("<U8 0 1 9223372036854775807>"); Assert.assertTrue(data instanceof U8); u8 = (U8) data; Assert.assertEquals(0x0000000000000000L, u8.getValue(0)); Assert.assertEquals(0x0000000000000001L, u8.getValue(1)); Assert.assertEquals(0x7fffffffffffffffL, u8.getValue(2)); }