The message encoders and decoders now catch exceptions, and throw InvalidMessageException.
Removed the big switch statement from BinaryMessageDecoder - it now uses the decoder factory instead. issue #35 #36 #story[1095]
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.AverageWind;
|
||||
import network.Utils.ByteConverter;
|
||||
@@ -32,64 +33,67 @@ public class AverageWindDecoder implements MessageDecoder {
|
||||
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
try {
|
||||
|
||||
byte messageVersionNumber = encodedMessage[0];
|
||||
byte messageVersionNumber = encodedMessage[0];
|
||||
|
||||
|
||||
byte[] byteTime = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = ByteConverter.bytesToLong(byteTime);
|
||||
byte[] byteTime = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = ByteConverter.bytesToLong(byteTime);
|
||||
|
||||
byte[] byteRawPeriod = Arrays.copyOfRange(encodedMessage, 7, 9);
|
||||
int intRawPeriod = ByteConverter.bytesToInt(byteRawPeriod);
|
||||
long rawPeriod = unpackAverageWindPeriod(intRawPeriod);
|
||||
byte[] byteRawPeriod = Arrays.copyOfRange(encodedMessage, 7, 9);
|
||||
int intRawPeriod = ByteConverter.bytesToInt(byteRawPeriod);
|
||||
long rawPeriod = unpackAverageWindPeriod(intRawPeriod);
|
||||
|
||||
byte[] byteRawSpeed = Arrays.copyOfRange(encodedMessage, 9, 11);
|
||||
int intRawSpeed = ByteConverter.bytesToInt(byteRawSpeed);
|
||||
double rawSpeedKnots = unpackMMperSecToKnots(intRawSpeed);
|
||||
byte[] byteRawSpeed = Arrays.copyOfRange(encodedMessage, 9, 11);
|
||||
int intRawSpeed = ByteConverter.bytesToInt(byteRawSpeed);
|
||||
double rawSpeedKnots = unpackMMperSecToKnots(intRawSpeed);
|
||||
|
||||
byte[] bytePeriod2 = Arrays.copyOfRange(encodedMessage, 11, 13);
|
||||
int intPeriod2 = ByteConverter.bytesToInt(bytePeriod2);
|
||||
long period2 = unpackAverageWindPeriod(intPeriod2);
|
||||
byte[] bytePeriod2 = Arrays.copyOfRange(encodedMessage, 11, 13);
|
||||
int intPeriod2 = ByteConverter.bytesToInt(bytePeriod2);
|
||||
long period2 = unpackAverageWindPeriod(intPeriod2);
|
||||
|
||||
byte[] byteSpeed2 = Arrays.copyOfRange(encodedMessage, 13, 15);
|
||||
int intSpeed2 = ByteConverter.bytesToInt(byteSpeed2);
|
||||
double speed2Knots = unpackMMperSecToKnots(intSpeed2);
|
||||
byte[] byteSpeed2 = Arrays.copyOfRange(encodedMessage, 13, 15);
|
||||
int intSpeed2 = ByteConverter.bytesToInt(byteSpeed2);
|
||||
double speed2Knots = unpackMMperSecToKnots(intSpeed2);
|
||||
|
||||
byte[] bytePeriod3 = Arrays.copyOfRange(encodedMessage, 15, 17);
|
||||
int intPeriod3 = ByteConverter.bytesToInt(bytePeriod3);
|
||||
long period3 = unpackAverageWindPeriod(intPeriod3);
|
||||
byte[] bytePeriod3 = Arrays.copyOfRange(encodedMessage, 15, 17);
|
||||
int intPeriod3 = ByteConverter.bytesToInt(bytePeriod3);
|
||||
long period3 = unpackAverageWindPeriod(intPeriod3);
|
||||
|
||||
byte[] byteSpeed3 = Arrays.copyOfRange(encodedMessage, 17, 19);
|
||||
int intSpeed3 = ByteConverter.bytesToInt(byteSpeed3);
|
||||
double speed3Knots = unpackMMperSecToKnots(intSpeed3);
|
||||
byte[] byteSpeed3 = Arrays.copyOfRange(encodedMessage, 17, 19);
|
||||
int intSpeed3 = ByteConverter.bytesToInt(byteSpeed3);
|
||||
double speed3Knots = unpackMMperSecToKnots(intSpeed3);
|
||||
|
||||
byte[] bytePeriod4 = Arrays.copyOfRange(encodedMessage, 19, 21);
|
||||
int intPeriod4 = ByteConverter.bytesToInt(bytePeriod4);
|
||||
long period4 = unpackAverageWindPeriod(intPeriod4);
|
||||
byte[] bytePeriod4 = Arrays.copyOfRange(encodedMessage, 19, 21);
|
||||
int intPeriod4 = ByteConverter.bytesToInt(bytePeriod4);
|
||||
long period4 = unpackAverageWindPeriod(intPeriod4);
|
||||
|
||||
byte[] byteSpeed4 = Arrays.copyOfRange(encodedMessage, 21, 23);
|
||||
int intSpeed4 = ByteConverter.bytesToInt(byteSpeed4);
|
||||
double speed4Knots = unpackMMperSecToKnots(intSpeed4);
|
||||
byte[] byteSpeed4 = Arrays.copyOfRange(encodedMessage, 21, 23);
|
||||
int intSpeed4 = ByteConverter.bytesToInt(byteSpeed4);
|
||||
double speed4Knots = unpackMMperSecToKnots(intSpeed4);
|
||||
|
||||
|
||||
message = new AverageWind(
|
||||
messageVersionNumber,
|
||||
time,
|
||||
rawPeriod,
|
||||
rawSpeedKnots,
|
||||
period2,
|
||||
speed2Knots,
|
||||
period3,
|
||||
speed3Knots,
|
||||
period4,
|
||||
speed4Knots);
|
||||
|
||||
return message;
|
||||
|
||||
message = new AverageWind(
|
||||
messageVersionNumber,
|
||||
time,
|
||||
rawPeriod,
|
||||
rawSpeedKnots,
|
||||
period2,
|
||||
speed2Knots,
|
||||
period3,
|
||||
speed3Knots,
|
||||
period4,
|
||||
speed4Knots );
|
||||
|
||||
return message;
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode AverageWind message.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.BoatAction;
|
||||
import network.Messages.Enums.BoatActionEnum;
|
||||
@@ -29,14 +30,19 @@ public class BoatActionDecoder implements MessageDecoder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
BoatActionEnum boatActionEnum = BoatActionEnum.fromByte(encodedMessage[0]);
|
||||
try {
|
||||
BoatActionEnum boatActionEnum = BoatActionEnum.fromByte(encodedMessage[0]);
|
||||
|
||||
message = new BoatAction(boatActionEnum);
|
||||
message = new BoatAction(boatActionEnum);
|
||||
|
||||
return message;
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode BoatAction message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.BoatLocation;
|
||||
import network.Messages.Enums.BoatLocationDeviceEnum;
|
||||
@@ -39,115 +40,121 @@ public class BoatLocationDecoder implements MessageDecoder {
|
||||
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
byte[] messageVersionNumberBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
|
||||
byte messageVersionNumber = messageVersionNumberBytes[0];
|
||||
try {
|
||||
|
||||
byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timeBytes);
|
||||
byte[] messageVersionNumberBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
|
||||
byte messageVersionNumber = messageVersionNumberBytes[0];
|
||||
|
||||
byte[] sourceIDBytes = Arrays.copyOfRange(encodedMessage, 7, 11);
|
||||
int sourceID = bytesToInt(sourceIDBytes);
|
||||
byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timeBytes);
|
||||
|
||||
byte[] seqNumBytes = Arrays.copyOfRange(encodedMessage, 11, 15);
|
||||
int seqNum = bytesToInt(seqNumBytes);
|
||||
byte[] sourceIDBytes = Arrays.copyOfRange(encodedMessage, 7, 11);
|
||||
int sourceID = bytesToInt(sourceIDBytes);
|
||||
|
||||
byte[] deviceTypeBytes = Arrays.copyOfRange(encodedMessage, 15, 16);
|
||||
BoatLocationDeviceEnum deviceType = BoatLocationDeviceEnum.fromByte(deviceTypeBytes[0]);
|
||||
byte[] seqNumBytes = Arrays.copyOfRange(encodedMessage, 11, 15);
|
||||
int seqNum = bytesToInt(seqNumBytes);
|
||||
|
||||
byte[] latitudeBytes = Arrays.copyOfRange(encodedMessage, 16, 20);
|
||||
int numLatitude = bytesToInt(latitudeBytes);
|
||||
double latitude = unpackGPS(numLatitude);
|
||||
byte[] deviceTypeBytes = Arrays.copyOfRange(encodedMessage, 15, 16);
|
||||
BoatLocationDeviceEnum deviceType = BoatLocationDeviceEnum.fromByte(deviceTypeBytes[0]);
|
||||
|
||||
byte[] longitudeBytes = Arrays.copyOfRange(encodedMessage, 20, 24);
|
||||
int numLongitude = bytesToInt(longitudeBytes);
|
||||
double longitude = unpackGPS(numLongitude);
|
||||
byte[] latitudeBytes = Arrays.copyOfRange(encodedMessage, 16, 20);
|
||||
int numLatitude = bytesToInt(latitudeBytes);
|
||||
double latitude = unpackGPS(numLatitude);
|
||||
|
||||
byte[] altitudeBytes = Arrays.copyOfRange(encodedMessage, 24, 28);
|
||||
int numAltitude = bytesToInt(altitudeBytes);
|
||||
byte[] longitudeBytes = Arrays.copyOfRange(encodedMessage, 20, 24);
|
||||
int numLongitude = bytesToInt(longitudeBytes);
|
||||
double longitude = unpackGPS(numLongitude);
|
||||
|
||||
byte[] headingBytes = Arrays.copyOfRange(encodedMessage, 28, 30);
|
||||
int numHeading = bytesToInt(headingBytes);
|
||||
Bearing heading = Bearing.fromDegrees(unpackHeading(numHeading));
|
||||
byte[] altitudeBytes = Arrays.copyOfRange(encodedMessage, 24, 28);
|
||||
int numAltitude = bytesToInt(altitudeBytes);
|
||||
|
||||
byte[] pitchBytes = Arrays.copyOfRange(encodedMessage, 30, 32);
|
||||
short numPitch = bytesToShort(pitchBytes);
|
||||
byte[] headingBytes = Arrays.copyOfRange(encodedMessage, 28, 30);
|
||||
int numHeading = bytesToInt(headingBytes);
|
||||
Bearing heading = Bearing.fromDegrees(unpackHeading(numHeading));
|
||||
|
||||
byte[] rollBytes = Arrays.copyOfRange(encodedMessage, 32, 34);
|
||||
short numRoll = bytesToShort(rollBytes);
|
||||
byte[] pitchBytes = Arrays.copyOfRange(encodedMessage, 30, 32);
|
||||
short numPitch = bytesToShort(pitchBytes);
|
||||
|
||||
byte[] boatSpeedBytes = Arrays.copyOfRange(encodedMessage, 34, 36);
|
||||
int numBoatSpeed = bytesToInt(boatSpeedBytes);
|
||||
double boatSpeedKnots = unpackMMperSecToKnots(numBoatSpeed);
|
||||
byte[] rollBytes = Arrays.copyOfRange(encodedMessage, 32, 34);
|
||||
short numRoll = bytesToShort(rollBytes);
|
||||
|
||||
byte[] cogBytes = Arrays.copyOfRange(encodedMessage, 36, 38);
|
||||
int numCog = bytesToInt(cogBytes);
|
||||
Bearing cog = Bearing.fromDegrees(unpackHeading(numCog));
|
||||
byte[] boatSpeedBytes = Arrays.copyOfRange(encodedMessage, 34, 36);
|
||||
int numBoatSpeed = bytesToInt(boatSpeedBytes);
|
||||
double boatSpeedKnots = unpackMMperSecToKnots(numBoatSpeed);
|
||||
|
||||
byte[] sogBytes = Arrays.copyOfRange(encodedMessage, 38, 40);
|
||||
int numSog = bytesToInt(sogBytes);
|
||||
double sogKnots = unpackMMperSecToKnots(numSog);
|
||||
byte[] cogBytes = Arrays.copyOfRange(encodedMessage, 36, 38);
|
||||
int numCog = bytesToInt(cogBytes);
|
||||
Bearing cog = Bearing.fromDegrees(unpackHeading(numCog));
|
||||
|
||||
byte[] apparentWindSpeedBytes = Arrays.copyOfRange(encodedMessage, 40, 42);
|
||||
int numApparentWindSpeed = bytesToInt(apparentWindSpeedBytes);
|
||||
double apparentWindSpeedKnots = unpackMMperSecToKnots(numApparentWindSpeed);
|
||||
byte[] sogBytes = Arrays.copyOfRange(encodedMessage, 38, 40);
|
||||
int numSog = bytesToInt(sogBytes);
|
||||
double sogKnots = unpackMMperSecToKnots(numSog);
|
||||
|
||||
byte[] apparentWindAngleBytes = Arrays.copyOfRange(encodedMessage, 42, 44);
|
||||
short numApparentWindAngle = bytesToShort(apparentWindAngleBytes);
|
||||
Azimuth apparentWindAngle = Azimuth.fromDegrees(unpackTrueWindAngle(numApparentWindAngle));
|
||||
byte[] apparentWindSpeedBytes = Arrays.copyOfRange(encodedMessage, 40, 42);
|
||||
int numApparentWindSpeed = bytesToInt(apparentWindSpeedBytes);
|
||||
double apparentWindSpeedKnots = unpackMMperSecToKnots(numApparentWindSpeed);
|
||||
|
||||
byte[] trueWindSpeedBytes = Arrays.copyOfRange(encodedMessage, 44, 46);
|
||||
int numTrueWindSpeed = bytesToInt(trueWindSpeedBytes);
|
||||
double trueWindSpeedKnots = unpackMMperSecToKnots(numTrueWindSpeed);
|
||||
byte[] apparentWindAngleBytes = Arrays.copyOfRange(encodedMessage, 42, 44);
|
||||
short numApparentWindAngle = bytesToShort(apparentWindAngleBytes);
|
||||
Azimuth apparentWindAngle = Azimuth.fromDegrees(unpackTrueWindAngle(numApparentWindAngle));
|
||||
|
||||
byte[] trueWindDirectionBytes = Arrays.copyOfRange(encodedMessage, 46, 48);
|
||||
short numTrueWindDirection = bytesToShort(trueWindDirectionBytes);
|
||||
Bearing trueWindDirection = Bearing.fromDegrees(unpackHeading(numTrueWindDirection));
|
||||
byte[] trueWindSpeedBytes = Arrays.copyOfRange(encodedMessage, 44, 46);
|
||||
int numTrueWindSpeed = bytesToInt(trueWindSpeedBytes);
|
||||
double trueWindSpeedKnots = unpackMMperSecToKnots(numTrueWindSpeed);
|
||||
|
||||
byte[] trueWindAngleBytes = Arrays.copyOfRange(encodedMessage, 48, 50);
|
||||
short numTrueWindAngle = bytesToShort(trueWindAngleBytes);
|
||||
Azimuth trueWindAngle = Azimuth.fromDegrees(unpackTrueWindAngle(numTrueWindAngle));
|
||||
byte[] trueWindDirectionBytes = Arrays.copyOfRange(encodedMessage, 46, 48);
|
||||
short numTrueWindDirection = bytesToShort(trueWindDirectionBytes);
|
||||
Bearing trueWindDirection = Bearing.fromDegrees(unpackHeading(numTrueWindDirection));
|
||||
|
||||
byte[] currentDriftBytes = Arrays.copyOfRange(encodedMessage, 50, 52);
|
||||
int numCurrentDrift = bytesToInt(currentDriftBytes);
|
||||
double currentDriftKnots = unpackMMperSecToKnots(numCurrentDrift);
|
||||
byte[] trueWindAngleBytes = Arrays.copyOfRange(encodedMessage, 48, 50);
|
||||
short numTrueWindAngle = bytesToShort(trueWindAngleBytes);
|
||||
Azimuth trueWindAngle = Azimuth.fromDegrees(unpackTrueWindAngle(numTrueWindAngle));
|
||||
|
||||
byte[] currentSetBytes = Arrays.copyOfRange(encodedMessage, 52, 54);
|
||||
int numCurrentSet = bytesToShort(currentSetBytes);
|
||||
Bearing currentSet = Bearing.fromDegrees(unpackHeading(numCurrentSet));
|
||||
byte[] currentDriftBytes = Arrays.copyOfRange(encodedMessage, 50, 52);
|
||||
int numCurrentDrift = bytesToInt(currentDriftBytes);
|
||||
double currentDriftKnots = unpackMMperSecToKnots(numCurrentDrift);
|
||||
|
||||
byte[] rudderAngleBytes = Arrays.copyOfRange(encodedMessage, 54, 56);
|
||||
short numRudderAngle = bytesToShort(rudderAngleBytes);
|
||||
Azimuth rudderAngle = Azimuth.fromDegrees(unpackTrueWindAngle(numRudderAngle));
|
||||
byte[] currentSetBytes = Arrays.copyOfRange(encodedMessage, 52, 54);
|
||||
int numCurrentSet = bytesToShort(currentSetBytes);
|
||||
Bearing currentSet = Bearing.fromDegrees(unpackHeading(numCurrentSet));
|
||||
|
||||
byte[] rudderAngleBytes = Arrays.copyOfRange(encodedMessage, 54, 56);
|
||||
short numRudderAngle = bytesToShort(rudderAngleBytes);
|
||||
Azimuth rudderAngle = Azimuth.fromDegrees(unpackTrueWindAngle(numRudderAngle));
|
||||
|
||||
|
||||
message = new BoatLocation(
|
||||
messageVersionNumber,
|
||||
time,
|
||||
sourceID,
|
||||
seqNum,
|
||||
deviceType,
|
||||
latitude,
|
||||
longitude,
|
||||
numAltitude,
|
||||
heading,
|
||||
numPitch,
|
||||
numRoll,
|
||||
boatSpeedKnots,
|
||||
cog,
|
||||
sogKnots,
|
||||
apparentWindSpeedKnots,
|
||||
apparentWindAngle,
|
||||
trueWindSpeedKnots,
|
||||
trueWindDirection,
|
||||
trueWindAngle,
|
||||
currentDriftKnots,
|
||||
currentSet,
|
||||
rudderAngle );
|
||||
message = new BoatLocation(
|
||||
messageVersionNumber,
|
||||
time,
|
||||
sourceID,
|
||||
seqNum,
|
||||
deviceType,
|
||||
latitude,
|
||||
longitude,
|
||||
numAltitude,
|
||||
heading,
|
||||
numPitch,
|
||||
numRoll,
|
||||
boatSpeedKnots,
|
||||
cog,
|
||||
sogKnots,
|
||||
apparentWindSpeedKnots,
|
||||
apparentWindAngle,
|
||||
trueWindSpeedKnots,
|
||||
trueWindDirection,
|
||||
trueWindAngle,
|
||||
currentDriftKnots,
|
||||
currentSet,
|
||||
rudderAngle);
|
||||
|
||||
return message;
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode BoatLocation message.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.BoatStatus;
|
||||
import network.Messages.Enums.BoatStatusEnum;
|
||||
|
||||
@@ -39,10 +40,12 @@ public class BoatStatusDecoder {
|
||||
* Decodes the contained message.
|
||||
* @param encodedMessage The message to decode.
|
||||
* @return The decoded message.
|
||||
* @throws InvalidMessageException Thrown if the encoded message is invalid in some way, or cannot be decoded.
|
||||
*/
|
||||
public BoatStatus decode(byte[] encodedMessage) {
|
||||
public BoatStatus decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
try {
|
||||
|
||||
byte[] sourceIDBytes = Arrays.copyOfRange(encodedMessage, 0, 4);
|
||||
int sourceID = bytesToInt(sourceIDBytes);
|
||||
@@ -76,6 +79,10 @@ public class BoatStatusDecoder {
|
||||
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode BoatStatus message.", e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.CourseWind;
|
||||
import shared.model.Bearing;
|
||||
|
||||
@@ -38,49 +39,55 @@ public class CourseWindDecoder {
|
||||
* Decodes the contained message.
|
||||
* @param encodedMessage The message to decode.
|
||||
* @return The decoded message.
|
||||
* @throws InvalidMessageException Thrown if the encoded message is invalid in some way, or cannot be decoded.
|
||||
*/
|
||||
public CourseWind decode(byte[] encodedMessage) {
|
||||
public CourseWind decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
byte[] windId = Arrays.copyOfRange(encodedMessage, 0, 1);
|
||||
try {
|
||||
|
||||
byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timeBytes);
|
||||
byte[] windId = Arrays.copyOfRange(encodedMessage, 0, 1);
|
||||
|
||||
byte[] raceIDBytes = Arrays.copyOfRange(encodedMessage, 7, 11);
|
||||
int raceIDInt = bytesToInt(raceIDBytes);
|
||||
byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timeBytes);
|
||||
|
||||
byte[] windDirectionBytes = Arrays.copyOfRange(encodedMessage, 11, 13);
|
||||
int windDirectionInt = bytesToInt(windDirectionBytes);
|
||||
Bearing windDirection = Bearing.fromDegrees(unpackHeading(windDirectionInt));
|
||||
byte[] raceIDBytes = Arrays.copyOfRange(encodedMessage, 7, 11);
|
||||
int raceIDInt = bytesToInt(raceIDBytes);
|
||||
|
||||
byte[] windSpeedBytes = Arrays.copyOfRange(encodedMessage, 13, 15);
|
||||
int windSpeedInt = bytesToInt(windSpeedBytes);
|
||||
double windSpeedKnots = unpackMMperSecToKnots(windSpeedInt);
|
||||
byte[] windDirectionBytes = Arrays.copyOfRange(encodedMessage, 11, 13);
|
||||
int windDirectionInt = bytesToInt(windDirectionBytes);
|
||||
Bearing windDirection = Bearing.fromDegrees(unpackHeading(windDirectionInt));
|
||||
|
||||
byte[] bestUpwindAngleBytes = Arrays.copyOfRange(encodedMessage, 15, 17);
|
||||
int bestUpwindAngleInt = bytesToInt(bestUpwindAngleBytes);
|
||||
Bearing bestUpwindAngle = Bearing.fromDegrees(unpackHeading(bestUpwindAngleInt));
|
||||
byte[] windSpeedBytes = Arrays.copyOfRange(encodedMessage, 13, 15);
|
||||
int windSpeedInt = bytesToInt(windSpeedBytes);
|
||||
double windSpeedKnots = unpackMMperSecToKnots(windSpeedInt);
|
||||
|
||||
byte[] bestDownwindAngleBytes = Arrays.copyOfRange(encodedMessage, 17, 19);
|
||||
int bestDownwindAngleInt = bytesToInt(bestDownwindAngleBytes);
|
||||
Bearing bestDownwindAngle = Bearing.fromDegrees(unpackHeading(bestDownwindAngleInt));
|
||||
byte[] bestUpwindAngleBytes = Arrays.copyOfRange(encodedMessage, 15, 17);
|
||||
int bestUpwindAngleInt = bytesToInt(bestUpwindAngleBytes);
|
||||
Bearing bestUpwindAngle = Bearing.fromDegrees(unpackHeading(bestUpwindAngleInt));
|
||||
|
||||
byte[] flags = Arrays.copyOfRange(encodedMessage, 19, 20);
|
||||
byte[] bestDownwindAngleBytes = Arrays.copyOfRange(encodedMessage, 17, 19);
|
||||
int bestDownwindAngleInt = bytesToInt(bestDownwindAngleBytes);
|
||||
Bearing bestDownwindAngle = Bearing.fromDegrees(unpackHeading(bestDownwindAngleInt));
|
||||
|
||||
byte[] flags = Arrays.copyOfRange(encodedMessage, 19, 20);
|
||||
|
||||
|
||||
message = new CourseWind(
|
||||
windId[0],
|
||||
time,
|
||||
raceIDInt,
|
||||
windDirection,
|
||||
windSpeedKnots,
|
||||
bestUpwindAngle,
|
||||
bestDownwindAngle,
|
||||
flags[0]);
|
||||
|
||||
message = new CourseWind(
|
||||
windId[0],
|
||||
time,
|
||||
raceIDInt,
|
||||
windDirection,
|
||||
windSpeedKnots,
|
||||
bestUpwindAngle,
|
||||
bestDownwindAngle,
|
||||
flags[0] );
|
||||
return message;
|
||||
|
||||
return message;
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode CourseWind message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.CourseWind;
|
||||
import network.Messages.CourseWinds;
|
||||
@@ -38,41 +39,46 @@ public class CourseWindsDecoder implements MessageDecoder {
|
||||
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
//The header is three bytes.
|
||||
byte messageVersionNumber = encodedMessage[0];
|
||||
byte byteWindID = encodedMessage[1];
|
||||
byte loopCount = encodedMessage[2];
|
||||
try {
|
||||
|
||||
//The header is three bytes.
|
||||
byte messageVersionNumber = encodedMessage[0];
|
||||
byte byteWindID = encodedMessage[1];
|
||||
byte loopCount = encodedMessage[2];
|
||||
|
||||
|
||||
//A CourseWind object is 20 bytes.
|
||||
final int courseWindByteLength = 20;
|
||||
//A CourseWind object is 20 bytes.
|
||||
final int courseWindByteLength = 20;
|
||||
|
||||
List<CourseWind> loopMessages = new ArrayList();
|
||||
List<CourseWind> loopMessages = new ArrayList();
|
||||
|
||||
//The header is 3 bytes, so we need the remaining bytes.
|
||||
byte[] loopMessagesBytes = Arrays.copyOfRange(encodedMessage, 3, courseWindByteLength * loopCount + 3);
|
||||
//The header is 3 bytes, so we need the remaining bytes.
|
||||
byte[] loopMessagesBytes = Arrays.copyOfRange(encodedMessage, 3, courseWindByteLength * loopCount + 3);
|
||||
|
||||
for (int messageLoopIndex = 0; messageLoopIndex < (loopCount * courseWindByteLength); messageLoopIndex += courseWindByteLength) {
|
||||
for (int messageLoopIndex = 0; messageLoopIndex < (loopCount * courseWindByteLength); messageLoopIndex += courseWindByteLength) {
|
||||
|
||||
byte[] messageBytes = Arrays.copyOfRange(loopMessagesBytes, messageLoopIndex, messageLoopIndex + courseWindByteLength);
|
||||
byte[] messageBytes = Arrays.copyOfRange(loopMessagesBytes, messageLoopIndex, messageLoopIndex + courseWindByteLength);
|
||||
|
||||
CourseWindDecoder courseWindDecoder = new CourseWindDecoder();
|
||||
CourseWind courseWind = courseWindDecoder.decode(messageBytes);
|
||||
CourseWindDecoder courseWindDecoder = new CourseWindDecoder();
|
||||
CourseWind courseWind = courseWindDecoder.decode(messageBytes);
|
||||
|
||||
loopMessages.add(courseWind);
|
||||
loopMessages.add(courseWind);
|
||||
}
|
||||
|
||||
|
||||
message = new CourseWinds(
|
||||
messageVersionNumber,
|
||||
byteWindID,
|
||||
loopMessages);
|
||||
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode CourseWinds message.", e);
|
||||
}
|
||||
|
||||
|
||||
|
||||
message = new CourseWinds(
|
||||
messageVersionNumber,
|
||||
byteWindID,
|
||||
loopMessages );
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.Enums.BoatActionEnum;
|
||||
import network.Messages.HeartBeat;
|
||||
@@ -30,12 +31,18 @@ public class HeartBeatDecoder implements MessageDecoder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
message = new HeartBeat(bytesToLong(encodedMessage));
|
||||
try {
|
||||
|
||||
return message;
|
||||
message = new HeartBeat(bytesToLong(encodedMessage));
|
||||
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode HeartBeat message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.Enums.JoinAcceptanceEnum;
|
||||
import network.Messages.JoinAcceptance;
|
||||
@@ -32,27 +33,32 @@ public class JoinAcceptanceDecoder implements MessageDecoder {
|
||||
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
//SourceID is first four bytes.
|
||||
byte[] sourceIdBytes = Arrays.copyOfRange(encodedMessage, 0, 4);
|
||||
try {
|
||||
|
||||
//Next byte is acceptance type.
|
||||
byte[] acceptanceBytes = Arrays.copyOfRange(encodedMessage, 4, 5);
|
||||
//SourceID is first four bytes.
|
||||
byte[] sourceIdBytes = Arrays.copyOfRange(encodedMessage, 0, 4);
|
||||
|
||||
//Next byte is acceptance type.
|
||||
byte[] acceptanceBytes = Arrays.copyOfRange(encodedMessage, 4, 5);
|
||||
|
||||
|
||||
//SourceID is an int.
|
||||
int sourceID = ByteConverter.bytesToInt(sourceIdBytes);
|
||||
|
||||
//SourceID is an int.
|
||||
int sourceID = ByteConverter.bytesToInt(sourceIdBytes);
|
||||
|
||||
//Acceptance enum is a byte.
|
||||
JoinAcceptanceEnum acceptanceType = JoinAcceptanceEnum.fromByte(acceptanceBytes[0]);
|
||||
//Acceptance enum is a byte.
|
||||
JoinAcceptanceEnum acceptanceType = JoinAcceptanceEnum.fromByte(acceptanceBytes[0]);
|
||||
|
||||
|
||||
message = new JoinAcceptance(acceptanceType, sourceID);
|
||||
message = new JoinAcceptance(acceptanceType, sourceID);
|
||||
|
||||
return message;
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode JoinAcceptance message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.Enums.MarkRoundingBoatStatusEnum;
|
||||
import network.Messages.Enums.MarkRoundingSideEnum;
|
||||
@@ -33,48 +34,54 @@ public class MarkRoundingDecoder implements MessageDecoder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
byte messageVersionNumber = encodedMessage[0];
|
||||
try {
|
||||
|
||||
byte[] byteTime = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = ByteConverter.bytesToLong(byteTime);
|
||||
byte messageVersionNumber = encodedMessage[0];
|
||||
|
||||
byte[] byteAck = Arrays.copyOfRange(encodedMessage, 7, 9);
|
||||
int ackNumber = ByteConverter.bytesToInt(byteAck);
|
||||
byte[] byteTime = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = ByteConverter.bytesToLong(byteTime);
|
||||
|
||||
byte[] byteRaceID = Arrays.copyOfRange(encodedMessage, 9, 13);
|
||||
int raceID = ByteConverter.bytesToInt(byteRaceID);
|
||||
byte[] byteAck = Arrays.copyOfRange(encodedMessage, 7, 9);
|
||||
int ackNumber = ByteConverter.bytesToInt(byteAck);
|
||||
|
||||
byte[] byteSourceID = Arrays.copyOfRange(encodedMessage, 13, 17);
|
||||
int sourceID = ByteConverter.bytesToInt(byteSourceID);
|
||||
byte[] byteRaceID = Arrays.copyOfRange(encodedMessage, 9, 13);
|
||||
int raceID = ByteConverter.bytesToInt(byteRaceID);
|
||||
|
||||
byte byteBoatStatus = encodedMessage[17];
|
||||
MarkRoundingBoatStatusEnum boatStatus = MarkRoundingBoatStatusEnum.fromByte(byteBoatStatus);
|
||||
byte[] byteSourceID = Arrays.copyOfRange(encodedMessage, 13, 17);
|
||||
int sourceID = ByteConverter.bytesToInt(byteSourceID);
|
||||
|
||||
byte byteRoundingSide = encodedMessage[18];
|
||||
MarkRoundingSideEnum roundingSide = MarkRoundingSideEnum.fromByte(byteRoundingSide);
|
||||
byte byteBoatStatus = encodedMessage[17];
|
||||
MarkRoundingBoatStatusEnum boatStatus = MarkRoundingBoatStatusEnum.fromByte(byteBoatStatus);
|
||||
|
||||
byte byteMarkType = encodedMessage[19];
|
||||
MarkRoundingTypeEnum markType = MarkRoundingTypeEnum.fromByte(byteMarkType);
|
||||
byte byteRoundingSide = encodedMessage[18];
|
||||
MarkRoundingSideEnum roundingSide = MarkRoundingSideEnum.fromByte(byteRoundingSide);
|
||||
|
||||
byte byteMarkID = encodedMessage[20];
|
||||
byte byteMarkType = encodedMessage[19];
|
||||
MarkRoundingTypeEnum markType = MarkRoundingTypeEnum.fromByte(byteMarkType);
|
||||
|
||||
byte byteMarkID = encodedMessage[20];
|
||||
|
||||
|
||||
message = new MarkRounding(
|
||||
messageVersionNumber,
|
||||
time,
|
||||
ackNumber,
|
||||
raceID,
|
||||
sourceID,
|
||||
boatStatus,
|
||||
roundingSide,
|
||||
markType,
|
||||
byteMarkID);
|
||||
message = new MarkRounding(
|
||||
messageVersionNumber,
|
||||
time,
|
||||
ackNumber,
|
||||
raceID,
|
||||
sourceID,
|
||||
boatStatus,
|
||||
roundingSide,
|
||||
markType,
|
||||
byteMarkID);
|
||||
|
||||
|
||||
return message;
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode AverageWind message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
|
||||
|
||||
@@ -15,7 +16,8 @@ public interface MessageDecoder {
|
||||
* Decodes a given message.
|
||||
* @param encodedMessage The message to decode.
|
||||
* @return The decoded message.
|
||||
* @throws InvalidMessageException Thrown if the encoded message is invalid in some way, or cannot be decoded.
|
||||
*/
|
||||
public AC35Data decode(byte[] encodedMessage);
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.Enums.RaceStartTypeEnum;
|
||||
import network.Messages.RaceStartStatus;
|
||||
@@ -35,38 +36,42 @@ public class RaceStartStatusDecoder implements MessageDecoder {
|
||||
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
try {
|
||||
|
||||
byte messageVersion = encodedMessage[0];
|
||||
byte messageVersion = encodedMessage[0];
|
||||
|
||||
byte[] timestamp = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timestamp);
|
||||
byte[] timestamp = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timestamp);
|
||||
|
||||
byte[] ackNumber = Arrays.copyOfRange(encodedMessage, 7, 9);
|
||||
short ack = bytesToShort(ackNumber);
|
||||
byte[] ackNumber = Arrays.copyOfRange(encodedMessage, 7, 9);
|
||||
short ack = bytesToShort(ackNumber);
|
||||
|
||||
byte[] raceStartTime = Arrays.copyOfRange(encodedMessage, 9, 15);
|
||||
long startTime = bytesToLong(raceStartTime);
|
||||
byte[] raceStartTime = Arrays.copyOfRange(encodedMessage, 9, 15);
|
||||
long startTime = bytesToLong(raceStartTime);
|
||||
|
||||
byte[] raceIdentifier = Arrays.copyOfRange(encodedMessage, 15, 19);
|
||||
int raceID = bytesToInt(raceIdentifier);
|
||||
byte[] raceIdentifier = Arrays.copyOfRange(encodedMessage, 15, 19);
|
||||
int raceID = bytesToInt(raceIdentifier);
|
||||
|
||||
byte notificationType = encodedMessage[19];
|
||||
byte notificationType = encodedMessage[19];
|
||||
|
||||
|
||||
message = new RaceStartStatus(
|
||||
messageVersion,
|
||||
time,
|
||||
ack,
|
||||
startTime,
|
||||
raceID,
|
||||
RaceStartTypeEnum.fromByte(notificationType)
|
||||
);
|
||||
|
||||
message = new RaceStartStatus(
|
||||
messageVersion,
|
||||
time,
|
||||
ack,
|
||||
startTime,
|
||||
raceID,
|
||||
RaceStartTypeEnum.fromByte(notificationType)
|
||||
);
|
||||
return message;
|
||||
|
||||
return message;
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode RaceStartStatus message.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.BoatStatus;
|
||||
import network.Messages.Enums.RaceStatusEnum;
|
||||
@@ -43,70 +44,75 @@ public class RaceStatusDecoder implements MessageDecoder {
|
||||
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
try {
|
||||
|
||||
byte[] versionNumBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
|
||||
byte versionNum = versionNumBytes[0];
|
||||
byte[] versionNumBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
|
||||
byte versionNum = versionNumBytes[0];
|
||||
|
||||
byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timeBytes);
|
||||
byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timeBytes);
|
||||
|
||||
byte[] raceIDBytes = Arrays.copyOfRange(encodedMessage, 7, 11);
|
||||
int raceID = bytesToInt(raceIDBytes);
|
||||
byte[] raceIDBytes = Arrays.copyOfRange(encodedMessage, 7, 11);
|
||||
int raceID = bytesToInt(raceIDBytes);
|
||||
|
||||
byte[] raceStatusBytes = Arrays.copyOfRange(encodedMessage, 11, 12);
|
||||
RaceStatusEnum raceStatus = RaceStatusEnum.fromByte(raceStatusBytes[0]);
|
||||
byte[] raceStatusBytes = Arrays.copyOfRange(encodedMessage, 11, 12);
|
||||
RaceStatusEnum raceStatus = RaceStatusEnum.fromByte(raceStatusBytes[0]);
|
||||
|
||||
byte[] expectedStartBytes = Arrays.copyOfRange(encodedMessage, 12, 18);
|
||||
long expectedStart = bytesToLong(expectedStartBytes);
|
||||
byte[] expectedStartBytes = Arrays.copyOfRange(encodedMessage, 12, 18);
|
||||
long expectedStart = bytesToLong(expectedStartBytes);
|
||||
|
||||
byte[] windDirectionBytes = Arrays.copyOfRange(encodedMessage, 18, 20);
|
||||
int windDirectionInt = bytesToInt(windDirectionBytes);
|
||||
Bearing windDirection = Bearing.fromDegrees(AC35UnitConverter.unpackHeading(windDirectionInt));
|
||||
byte[] windDirectionBytes = Arrays.copyOfRange(encodedMessage, 18, 20);
|
||||
int windDirectionInt = bytesToInt(windDirectionBytes);
|
||||
Bearing windDirection = Bearing.fromDegrees(AC35UnitConverter.unpackHeading(windDirectionInt));
|
||||
|
||||
byte[] windSpeedBytes = Arrays.copyOfRange(encodedMessage, 20, 22);
|
||||
int windSpeedInt = bytesToInt(windSpeedBytes);
|
||||
double windSpeedKnots = AC35UnitConverter.unpackMMperSecToKnots(windSpeedInt);
|
||||
byte[] windSpeedBytes = Arrays.copyOfRange(encodedMessage, 20, 22);
|
||||
int windSpeedInt = bytesToInt(windSpeedBytes);
|
||||
double windSpeedKnots = AC35UnitConverter.unpackMMperSecToKnots(windSpeedInt);
|
||||
|
||||
byte[] numberOfBoatsBytes = Arrays.copyOfRange(encodedMessage, 22, 23);
|
||||
int numberOfBoats = bytesToInt(numberOfBoatsBytes);
|
||||
byte[] numberOfBoatsBytes = Arrays.copyOfRange(encodedMessage, 22, 23);
|
||||
int numberOfBoats = bytesToInt(numberOfBoatsBytes);
|
||||
|
||||
byte[] raceTypeBytes = Arrays.copyOfRange(encodedMessage, 23, 24);
|
||||
RaceTypeEnum raceType = RaceTypeEnum.fromByte(raceTypeBytes[0]);
|
||||
byte[] raceTypeBytes = Arrays.copyOfRange(encodedMessage, 23, 24);
|
||||
RaceTypeEnum raceType = RaceTypeEnum.fromByte(raceTypeBytes[0]);
|
||||
|
||||
byte[] boatStatusesBytes = Arrays.copyOfRange(encodedMessage, 24, 25 + 20 * numberOfBoats);
|
||||
List<BoatStatus> boatStatuses = new ArrayList<>();
|
||||
byte[] boatStatusesBytes = Arrays.copyOfRange(encodedMessage, 24, 25 + 20 * numberOfBoats);
|
||||
List<BoatStatus> boatStatuses = new ArrayList<>();
|
||||
|
||||
|
||||
//BoatStatus is 20 bytes.
|
||||
int boatStatusByteLength = 20;
|
||||
//BoatStatus is 20 bytes.
|
||||
int boatStatusByteLength = 20;
|
||||
|
||||
|
||||
//Decode each BoatStatus.
|
||||
for (int boatLoopIndex = 0; boatLoopIndex < (numberOfBoats * boatStatusByteLength); boatLoopIndex += boatStatusByteLength) {
|
||||
//Decode each BoatStatus.
|
||||
for (int boatLoopIndex = 0; boatLoopIndex < (numberOfBoats * boatStatusByteLength); boatLoopIndex += boatStatusByteLength) {
|
||||
|
||||
byte[] boatStatusBytes = Arrays.copyOfRange(boatStatusesBytes, boatLoopIndex, boatLoopIndex + boatStatusByteLength);
|
||||
byte[] boatStatusBytes = Arrays.copyOfRange(boatStatusesBytes, boatLoopIndex, boatLoopIndex + boatStatusByteLength);
|
||||
|
||||
BoatStatusDecoder boatStatusDecoder = new BoatStatusDecoder();
|
||||
BoatStatusDecoder boatStatusDecoder = new BoatStatusDecoder();
|
||||
|
||||
boatStatuses.add(boatStatusDecoder.decode(boatStatusBytes));
|
||||
boatStatuses.add(boatStatusDecoder.decode(boatStatusBytes));
|
||||
}
|
||||
|
||||
|
||||
message = new RaceStatus(
|
||||
versionNum,
|
||||
time,
|
||||
raceID,
|
||||
raceStatus,
|
||||
expectedStart,
|
||||
windDirection,
|
||||
windSpeedKnots,
|
||||
raceType,
|
||||
boatStatuses);
|
||||
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode RaceStatus message.", e);
|
||||
}
|
||||
|
||||
|
||||
message = new RaceStatus(
|
||||
versionNum,
|
||||
time,
|
||||
raceID,
|
||||
raceStatus,
|
||||
expectedStart,
|
||||
windDirection,
|
||||
windSpeedKnots,
|
||||
raceType,
|
||||
boatStatuses );
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.Enums.RequestToJoinEnum;
|
||||
import network.Messages.RequestToJoin;
|
||||
@@ -31,20 +32,26 @@ public class RequestToJoinDecoder implements MessageDecoder{
|
||||
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedRequest) {
|
||||
public AC35Data decode(byte[] encodedRequest) throws InvalidMessageException {
|
||||
this.encodedRequest = encodedRequest;
|
||||
|
||||
//Request type is first four bytes.
|
||||
byte[] requestTypeBytes = Arrays.copyOfRange(encodedRequest, 0, 4);
|
||||
try {
|
||||
|
||||
//Request type is an integral type.
|
||||
int requestTypeInt = ByteConverter.bytesToInt(requestTypeBytes);
|
||||
RequestToJoinEnum requestType = RequestToJoinEnum.fromInt(requestTypeInt);
|
||||
//Request type is first four bytes.
|
||||
byte[] requestTypeBytes = Arrays.copyOfRange(encodedRequest, 0, 4);
|
||||
|
||||
//Request type is an integral type.
|
||||
int requestTypeInt = ByteConverter.bytesToInt(requestTypeBytes);
|
||||
RequestToJoinEnum requestType = RequestToJoinEnum.fromInt(requestTypeInt);
|
||||
|
||||
|
||||
message = new RequestToJoin(requestType);
|
||||
message = new RequestToJoin(requestType);
|
||||
|
||||
return message;
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode RequestToJoin message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
import network.Exceptions.InvalidMessageException;
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.Enums.XMLMessageType;
|
||||
import network.Messages.XMLMessage;
|
||||
@@ -35,36 +36,42 @@ public class XMLMessageDecoder implements MessageDecoder {
|
||||
|
||||
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
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);
|
||||
try {
|
||||
|
||||
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);
|
||||
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 );
|
||||
message = new XMLMessage(
|
||||
messageVersionNumber,
|
||||
ackNumber,
|
||||
timeStamp,
|
||||
xmlMsgSubType,
|
||||
sequenceNumber,
|
||||
xmlMessage);
|
||||
|
||||
return message;
|
||||
return message;
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new InvalidMessageException("Could not decode XMLMessage message.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user