Added XMLMessageEncoder.

Refactored XMLMessageDecoder to be consistent with other decoders - only needs to expose the XMLMessage.
Refactored BoatLocationDecoder to be consistent with other decoders - only needs to expose the BoatLocation.
Updated XMLMessageDecoderTest to use new encoder/decoder. Also tests all three message types.
Removed XMLMessageEncoderTest as it was redundant.
Updated BinaryMessageDecoderTest.xmlMessageTest() to use updated XMLMessage encoder/decoder.
issue #35 #36
#story[1095]
This commit is contained in:
fjc40
2017-08-06 01:01:05 +12:00
parent 8ef906472b
commit b486f99dbe
13 changed files with 535 additions and 317 deletions
@@ -11,132 +11,138 @@ import static network.Utils.ByteConverter.bytesToShort;
/**
* Created by hba56 on 21/04/17.
* Decodes {@link BoatLocation} messages.
*/
public class BoatLocationDecoder {
private byte messageVersionNumber;
private byte[] time;
private byte[] sourceID;
private byte[] seqNum;
private byte deviceType;
private byte[] latitude;
private byte[] longitude;
private byte[] altitude;
private byte[] heading;
private byte[] pitch;
private byte[] roll;
private byte[] boatSpeed;
private byte[] cog;
private byte[] sog;
private byte[] apparentWindSpeed;
private byte[] apparentWindAngle;
private byte[] trueWindSpeed;
private byte[] trueWindDirection;
private byte[] trueWindAngle;
private byte[] currentDrift;
private byte[] currentSet;
private byte[] rudderAngle;
/**
* The encoded message.
*/
private byte[] encodedMessage;
/**
* The decoded message.
*/
private BoatLocation message;
public BoatLocationDecoder(byte[] encodedBoatLocation) {
byte numMessageVersionNumber = 0;
long numTime = 0;
int numSourceID = 0;
int numSeqNum = 0;
byte numDeviceType = 0;
int numLatitude = 0;
int numLongitude = 0;
int numAltitude = 0;
int numHeading = 0;
short numPitch = 0;
short numRoll = 0;
int numBoatSpeed = 0;
int numCog = 0;
int numSog = 0;
int numApparentWindSpeed = 0;
short numApparentWindAngle = 0;
int numTrueWindSpeed = 0;
short numTrueWindDirection = 0;
short numTrueWindAngle = 0;
int numCurrentDrift = 0;
int numCurrentSet = 0;
short numRudderAngle = 0;
try {
messageVersionNumber = encodedBoatLocation[0];
numMessageVersionNumber = messageVersionNumber;
time = Arrays.copyOfRange(encodedBoatLocation, 1, 7);
numTime = bytesToLong(time);
sourceID = Arrays.copyOfRange(encodedBoatLocation, 7, 11);
numSourceID = bytesToInt(sourceID);
seqNum = Arrays.copyOfRange(encodedBoatLocation, 11, 15);
numSeqNum = bytesToInt(seqNum);
deviceType = encodedBoatLocation[15];
numDeviceType = deviceType;
latitude = Arrays.copyOfRange(encodedBoatLocation, 16, 20);
numLatitude = bytesToInt(latitude);
longitude = Arrays.copyOfRange(encodedBoatLocation, 20, 24);
numLongitude = bytesToInt(longitude);
altitude = Arrays.copyOfRange(encodedBoatLocation, 24, 28);
numAltitude = bytesToInt(altitude);
heading = Arrays.copyOfRange(encodedBoatLocation, 28, 30);
numHeading = bytesToInt(heading);
pitch = Arrays.copyOfRange(encodedBoatLocation, 30, 32);
numPitch = bytesToShort(pitch);
roll = Arrays.copyOfRange(encodedBoatLocation, 32, 34);
numRoll = bytesToShort(roll);
boatSpeed = Arrays.copyOfRange(encodedBoatLocation, 34, 36);
numBoatSpeed = bytesToInt(boatSpeed);
cog = Arrays.copyOfRange(encodedBoatLocation, 36, 38);
numCog = bytesToInt(cog);
sog = Arrays.copyOfRange(encodedBoatLocation, 38, 40);
numSog = bytesToInt(sog);
apparentWindSpeed = Arrays.copyOfRange(encodedBoatLocation, 40, 42);
numApparentWindSpeed = bytesToInt(apparentWindSpeed);
apparentWindAngle = Arrays.copyOfRange(encodedBoatLocation, 42, 44);
numApparentWindAngle = bytesToShort(apparentWindAngle);
trueWindSpeed = Arrays.copyOfRange(encodedBoatLocation, 44, 46);
numTrueWindSpeed = bytesToInt(trueWindSpeed);
trueWindDirection = Arrays.copyOfRange(encodedBoatLocation, 46, 48);
numTrueWindDirection = bytesToShort(trueWindDirection);
trueWindAngle = Arrays.copyOfRange(encodedBoatLocation, 48, 50);
numTrueWindAngle = bytesToShort(trueWindAngle);
currentDrift = Arrays.copyOfRange(encodedBoatLocation, 50, 52);
numCurrentDrift = bytesToInt(currentDrift);
currentSet = Arrays.copyOfRange(encodedBoatLocation, 52, 54);
numCurrentSet = bytesToShort(currentSet);
rudderAngle = Arrays.copyOfRange(encodedBoatLocation, 54, 56);
numRudderAngle = bytesToShort(rudderAngle);
} catch(ArrayIndexOutOfBoundsException e){
}
message = new BoatLocation(numMessageVersionNumber, numTime,
numSourceID, numSeqNum, numDeviceType, numLatitude,
numLongitude, numAltitude, numHeading, numPitch,
numRoll, numBoatSpeed, numCog, numSog, numApparentWindSpeed,
numApparentWindAngle, numTrueWindSpeed, numTrueWindDirection,
numTrueWindAngle, numCurrentDrift, numCurrentSet, numRudderAngle
);/*
message = new BoatLocation(messageVersionNumber, bytesToLong(time),
bytesToInt(sourceID), bytesToInt(seqNum),
deviceType, bytesToInt(latitude),
bytesToInt(longitude), bytesToInt(altitude),
bytesToInt(heading), bytesToShort(pitch),
bytesToShort(roll), bytesToInt(boatSpeed),
bytesToInt(cog), bytesToInt(sog),
bytesToInt(apparentWindSpeed), bytesToShort(apparentWindAngle),
bytesToInt(trueWindSpeed), bytesToShort(trueWindDirection),
bytesToShort(trueWindAngle), bytesToInt(currentDrift),
bytesToInt(currentSet), bytesToShort(rudderAngle)
);*/
/**
* Constructs a decoder to decode a given message.
* @param encodedMessage The message to decode.
*/
public BoatLocationDecoder(byte[] encodedMessage) {
// System.out.println(bytesToInt(sourceID));
// System.out.println(bytesToInt(boatSpeed));
this.encodedMessage = encodedMessage;
decode();
}
/**
* Decodes the contained message.
*/
private void decode() {
byte[] messageVersionNumber = Arrays.copyOfRange(encodedMessage, 0, 1);
byte numMessageVersionNumber = messageVersionNumber[0];
byte[] time = Arrays.copyOfRange(encodedMessage, 1, 7);
long numTime = bytesToLong(time);
byte[] sourceID = Arrays.copyOfRange(encodedMessage, 7, 11);
int numSourceID = bytesToInt(sourceID);
byte[] seqNum = Arrays.copyOfRange(encodedMessage, 11, 15);
int numSeqNum = bytesToInt(seqNum);
byte[] deviceType = Arrays.copyOfRange(encodedMessage, 15, 16);
byte numDeviceType = deviceType[0];
byte[] latitude = Arrays.copyOfRange(encodedMessage, 16, 20);
int numLatitude = bytesToInt(latitude);
byte[] longitude = Arrays.copyOfRange(encodedMessage, 20, 24);
int numLongitude = bytesToInt(longitude);
byte[] altitude = Arrays.copyOfRange(encodedMessage, 24, 28);
int numAltitude = bytesToInt(altitude);
byte[] heading = Arrays.copyOfRange(encodedMessage, 28, 30);
int numHeading = bytesToInt(heading);
byte[] pitch = Arrays.copyOfRange(encodedMessage, 30, 32);
short numPitch = bytesToShort(pitch);
byte[] roll = Arrays.copyOfRange(encodedMessage, 32, 34);
short numRoll = bytesToShort(roll);
byte[] boatSpeed = Arrays.copyOfRange(encodedMessage, 34, 36);
int numBoatSpeed = bytesToInt(boatSpeed);
byte[] cog = Arrays.copyOfRange(encodedMessage, 36, 38);
int numCog = bytesToInt(cog);
byte[] sog = Arrays.copyOfRange(encodedMessage, 38, 40);
int numSog = bytesToInt(sog);
byte[] apparentWindSpeed = Arrays.copyOfRange(encodedMessage, 40, 42);
int numApparentWindSpeed = bytesToInt(apparentWindSpeed);
byte[] apparentWindAngle = Arrays.copyOfRange(encodedMessage, 42, 44);
short numApparentWindAngle = bytesToShort(apparentWindAngle);
byte[] trueWindSpeed = Arrays.copyOfRange(encodedMessage, 44, 46);
int numTrueWindSpeed = bytesToInt(trueWindSpeed);
byte[] trueWindDirection = Arrays.copyOfRange(encodedMessage, 46, 48);
short numTrueWindDirection = bytesToShort(trueWindDirection);
byte[] trueWindAngle = Arrays.copyOfRange(encodedMessage, 48, 50);
short numTrueWindAngle = bytesToShort(trueWindAngle);
byte[] currentDrift = Arrays.copyOfRange(encodedMessage, 50, 52);
int numCurrentDrift = bytesToInt(currentDrift);
byte[] currentSet = Arrays.copyOfRange(encodedMessage, 52, 54);
int numCurrentSet = bytesToShort(currentSet);
byte[] rudderAngle = Arrays.copyOfRange(encodedMessage, 54, 56);
short numRudderAngle = bytesToShort(rudderAngle);
message = new BoatLocation(
numMessageVersionNumber,
numTime,
numSourceID,
numSeqNum,
numDeviceType,
numLatitude,
numLongitude,
numAltitude,
numHeading,
numPitch,
numRoll,
numBoatSpeed,
numCog,
numSog,
numApparentWindSpeed,
numApparentWindAngle,
numTrueWindSpeed,
numTrueWindDirection,
numTrueWindAngle,
numCurrentDrift,
numCurrentSet,
numRudderAngle );
}
/**
* Returns the decoded message.
* @return The decoded message.
*/
public BoatLocation getMessage() {
return message;
}
@@ -1,10 +1,8 @@
package network.MessageDecoders;
import network.Messages.Enums.XMLMessageType;
import network.Messages.XMLMessage;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import static network.Utils.ByteConverter.bytesToLong;
@@ -12,73 +10,70 @@ import static network.Utils.ByteConverter.bytesToShort;
/**
* Created by hba56 on 20/04/17.
* Decodes {@link network.Messages.XMLMessage} messages.
*/
public class XMLMessageDecoder {
private byte messageVersionNumber;
private short ackNumber;
private long timeStamp;
private byte xmlMsgSubType;
private short sequenceNumber;
private short xmlMsgLength;
private String xmlMessage;
private byte[] bytes;
/**
* The encoded message.
*/
private byte[] encodedMessage;
public XMLMessageDecoder(byte[] bytes) {
this.bytes = bytes;
}
public void decode(){
byte[] ackNumberBytes = Arrays.copyOfRange(bytes, 1, 3);
byte[] timeStampBytes = Arrays.copyOfRange(bytes, 3, 9);
byte[] sequenceNumberBytes = Arrays.copyOfRange(bytes, 10, 12);
byte[] xmlMsgLengthBytes = Arrays.copyOfRange(bytes, 12, 14);
byte[] xmlMessagebytes = Arrays.copyOfRange(bytes, 14, bytes.length);
this.xmlMsgSubType = bytes[9];
this.messageVersionNumber = bytes[0];
this.ackNumber = bytesToShort(ackNumberBytes);
this.timeStamp = bytesToLong(timeStampBytes);
this.sequenceNumber = bytesToShort(sequenceNumberBytes);
this.xmlMsgLength = bytesToShort(xmlMsgLengthBytes);
this.xmlMessage = new String(xmlMessagebytes).trim();
}
public byte getMessageVersionNumber() {
return messageVersionNumber;
}
public short getAckNumber() {
return ackNumber;
}
public long getTimeStamp() {
return timeStamp;
}
public XMLMessageType getXmlMsgSubType() {
return XMLMessageType.fromByte(xmlMsgSubType);
}
public short getSequenceNumber() {
return sequenceNumber;
}
public short getXmlMsgLength() {
return xmlMsgLength;
}
/**
* The decoded message.
*/
private XMLMessage message;
/**
* Returns the contents of the XML message (e.g., the contents of a race.xml file).
* @return The contents of the XML message.
* Constructs a decoder to decode a given message.
* @param encodedMessage The message to decode.
*/
public String getXmlMessageContents() {
return xmlMessage;
public XMLMessageDecoder(byte[] encodedMessage) {
this.encodedMessage = encodedMessage;
decode();
}
/**
* Decodes the contained message.
*/
private void decode() {
byte[] messageVersionNumberBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
byte[] ackNumberBytes = Arrays.copyOfRange(encodedMessage, 1, 3);
byte[] timeStampBytes = Arrays.copyOfRange(encodedMessage, 3, 9);
byte[] xmlMsgSubTypeBytes = Arrays.copyOfRange(encodedMessage, 9, 10);
byte[] sequenceNumberBytes = Arrays.copyOfRange(encodedMessage, 10, 12);
byte[] xmlMsgLengthBytes = Arrays.copyOfRange(encodedMessage, 12, 14);
byte[] xmlMessagebytes = Arrays.copyOfRange(encodedMessage, 14, encodedMessage.length);
byte messageVersionNumber = messageVersionNumberBytes[0];
short ackNumber = bytesToShort(ackNumberBytes);
long timeStamp = bytesToLong(timeStampBytes);
XMLMessageType xmlMsgSubType = XMLMessageType.fromByte(xmlMsgSubTypeBytes[0]);
short sequenceNumber = bytesToShort(sequenceNumberBytes);
short xmlMsgLength = bytesToShort(xmlMsgLengthBytes);
String xmlMessage = new String(xmlMessagebytes);
message = new XMLMessage(
messageVersionNumber,
ackNumber,
timeStamp,
xmlMsgSubType,
sequenceNumber,
xmlMessage );
}
/**
* Returns the decoded message.
* @return The decoded message.
*/
public XMLMessage getMessage() {
return message;
}
}