Added RaceStatusEncoder.
Refactored RaceStatusDecoder to be more consistent with other decoders - it now has a getMessage() function. Added BoatStatus encoder and decoder - the RaceStatus encoder and decoder uses this for BoatStatuses. The BoatStatus encoder doesn't implement the MessageEncoder interface as BoatStatus is not a proper message type (doesn't inherit from AC35Data). Added remaining cases to EncoderFactory, but commented them out. BoatStatus now uses BoatStatusEnum instead of a byte. Added some comments to RaceStatus, and it uses enums instead of bytes. MockOutput logs a warning if a RaceStatus cannot be encoded. Added a BoatStatusDecoderTest. Updated RaceStatusDecoder to use new encoders/decoders. issue #35 #36 #story[1095]
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Messages.BoatStatus;
|
||||
import network.Messages.Enums.BoatStatusEnum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static network.Utils.ByteConverter.*;
|
||||
|
||||
|
||||
/**
|
||||
* Decodes {@link BoatStatus} messages.
|
||||
*/
|
||||
public class BoatStatusDecoder {
|
||||
|
||||
/**
|
||||
* The encoded message.
|
||||
*/
|
||||
private byte[] encodedMessage;
|
||||
|
||||
/**
|
||||
* The decoded message.
|
||||
*/
|
||||
private BoatStatus message;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a decoder to decode a given message.
|
||||
* @param encodedMessage The message to decode.
|
||||
*/
|
||||
public BoatStatusDecoder(byte[] encodedMessage) {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
decode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decodes the contained message.
|
||||
*/
|
||||
private void decode() {
|
||||
|
||||
|
||||
byte[] sourceIDBytes = Arrays.copyOfRange(encodedMessage, 0, 4);
|
||||
int sourceID = bytesToInt(sourceIDBytes);
|
||||
|
||||
byte[] boatStatusBytes = Arrays.copyOfRange(encodedMessage, 4, 5);
|
||||
BoatStatusEnum boatStatus = BoatStatusEnum.fromByte(boatStatusBytes[0]);
|
||||
|
||||
byte[] legNumberBytes = Arrays.copyOfRange(encodedMessage, 5, 6);
|
||||
byte legNumber = legNumberBytes[0];
|
||||
|
||||
byte[] numPenaltiesAwardedBytes = Arrays.copyOfRange(encodedMessage, 6, 7);
|
||||
byte numPenaltiesAwarded = numPenaltiesAwardedBytes[0];
|
||||
|
||||
byte[] numPenaltiesServedBytes = Arrays.copyOfRange(encodedMessage, 7, 8);
|
||||
byte numPenaltiesServed = numPenaltiesServedBytes[0];
|
||||
|
||||
byte[] estTimeAtNextMarkBytes = Arrays.copyOfRange(encodedMessage, 8, 14);
|
||||
long estTimeAtNextMark = bytesToLong(estTimeAtNextMarkBytes);
|
||||
|
||||
byte[] estTimeAtFinishBytes = Arrays.copyOfRange(encodedMessage, 14, 20);
|
||||
long estTimeAtFinish = bytesToLong(estTimeAtFinishBytes);
|
||||
|
||||
message = new BoatStatus(
|
||||
sourceID,
|
||||
boatStatus,
|
||||
legNumber,
|
||||
numPenaltiesAwarded,
|
||||
numPenaltiesServed,
|
||||
estTimeAtNextMark,
|
||||
estTimeAtFinish );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the decoded message.
|
||||
* @return The decoded message.
|
||||
*/
|
||||
public BoatStatus getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,13 @@ package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Messages.BoatStatus;
|
||||
import network.Messages.Enums.RaceStatusEnum;
|
||||
import network.Messages.Enums.RaceTypeEnum;
|
||||
import network.Messages.RaceStatus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static network.Utils.ByteConverter.bytesToInt;
|
||||
import static network.Utils.ByteConverter.bytesToLong;
|
||||
@@ -12,110 +16,101 @@ import static network.Utils.ByteConverter.bytesToShort;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hba56 on 21/04/17.
|
||||
* Decodes {@link RaceStatus} messages.
|
||||
*/
|
||||
public class RaceStatusDecoder {
|
||||
private byte versionNum;
|
||||
private byte[] timeBytes;
|
||||
private byte[] raceID;
|
||||
private byte raceStatus;
|
||||
private byte[] expectedStart;
|
||||
private byte[] raceWind;
|
||||
private byte[] windSpeed;
|
||||
private byte numBoats;
|
||||
private byte bytesRaceType;
|
||||
private byte[] boatsBytes;
|
||||
|
||||
private long time;
|
||||
private int race;
|
||||
private byte raceState;
|
||||
private long startTime;
|
||||
private int raceWindDir;
|
||||
private short raceWindSpeed;
|
||||
private int numberOfBoats;
|
||||
private int raceType;
|
||||
private ArrayList<BoatStatus> boats = new ArrayList<>();
|
||||
/**
|
||||
* The encoded message.
|
||||
*/
|
||||
private byte[] encodedMessage;
|
||||
|
||||
/**
|
||||
* The decoded message.
|
||||
*/
|
||||
private RaceStatus message;
|
||||
|
||||
|
||||
public RaceStatusDecoder(byte[] encodedRaceStatus){
|
||||
versionNum = encodedRaceStatus[0];
|
||||
timeBytes = Arrays.copyOfRange(encodedRaceStatus, 1, 7);
|
||||
raceID = Arrays.copyOfRange(encodedRaceStatus, 7, 11);
|
||||
raceStatus = encodedRaceStatus[11];
|
||||
expectedStart = Arrays.copyOfRange(encodedRaceStatus, 12, 18);
|
||||
raceWind = Arrays.copyOfRange(encodedRaceStatus, 18, 20);
|
||||
windSpeed = Arrays.copyOfRange(encodedRaceStatus, 20, 22);
|
||||
numBoats = encodedRaceStatus[22];
|
||||
bytesRaceType = encodedRaceStatus[23];
|
||||
boatsBytes = Arrays.copyOfRange(encodedRaceStatus, 24, 25+20*this.numBoats);
|
||||
|
||||
time = bytesToLong(timeBytes);
|
||||
race = bytesToInt(raceID);
|
||||
raceState = raceStatus;
|
||||
startTime = bytesToLong(expectedStart);
|
||||
raceWindDir = bytesToInt(raceWind);
|
||||
raceWindSpeed = bytesToShort(windSpeed);
|
||||
numberOfBoats = bytesToInt(numBoats);
|
||||
/**
|
||||
* Constructs a decoder to decode a given message.
|
||||
* @param encodedMessage The message to decode.
|
||||
*/
|
||||
public RaceStatusDecoder(byte[] encodedMessage) {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
int boatLoopIndex = 0;
|
||||
decode();
|
||||
}
|
||||
|
||||
for (int i=0; i < numberOfBoats; i++) {
|
||||
byte[] boatBytes = Arrays.copyOfRange(boatsBytes, boatLoopIndex, boatLoopIndex+20);
|
||||
|
||||
byte[] sourceID = Arrays.copyOfRange(boatBytes, 0, 3);
|
||||
byte boatStatus = boatBytes[4];
|
||||
byte legNumber = boatBytes[5];
|
||||
byte numPenaltiesAwarded = boatBytes[6];
|
||||
byte numPenaltiesServed = boatBytes[7];
|
||||
byte[] estTimeAtNextMark = Arrays.copyOfRange(boatBytes, 8, 14);
|
||||
byte[] estTimeAtFinish = Arrays.copyOfRange(boatBytes, 14, 20);
|
||||
/**
|
||||
* Decodes the contained message.
|
||||
*/
|
||||
private void decode() {
|
||||
|
||||
BoatStatus boat = new BoatStatus(bytesToInt(sourceID),boatStatus,
|
||||
legNumber, numPenaltiesAwarded, numPenaltiesServed,
|
||||
bytesToLong(estTimeAtNextMark), bytesToLong(estTimeAtFinish));
|
||||
|
||||
boats.add(boat);
|
||||
boatLoopIndex += 20;
|
||||
byte[] versionNumBytes = Arrays.copyOfRange(encodedMessage, 0, 1);
|
||||
byte versionNum = versionNumBytes[0];
|
||||
|
||||
byte[] timeBytes = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timeBytes);
|
||||
|
||||
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[] expectedStartBytes = Arrays.copyOfRange(encodedMessage, 12, 18);
|
||||
long expectedStart = bytesToLong(expectedStartBytes);
|
||||
|
||||
byte[] windDirectionBytes = Arrays.copyOfRange(encodedMessage, 18, 20);
|
||||
int windDirection = bytesToInt(windDirectionBytes);
|
||||
|
||||
byte[] windSpeedBytes = Arrays.copyOfRange(encodedMessage, 20, 22);
|
||||
short windSpeed = bytesToShort(windSpeedBytes);
|
||||
|
||||
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[] boatStatusesBytes = Arrays.copyOfRange(encodedMessage, 24, 25 + 20 * numberOfBoats);
|
||||
List<BoatStatus> boatStatuses = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
//Decode each BoatStatus.
|
||||
for (int boatLoopIndex=0; boatLoopIndex < (numberOfBoats * 20); boatLoopIndex += 20) {
|
||||
|
||||
byte[] boatStatusBytes = Arrays.copyOfRange(boatStatusesBytes, boatLoopIndex, boatLoopIndex + 20);
|
||||
|
||||
BoatStatusDecoder boatStatusDecoder = new BoatStatusDecoder(boatStatusBytes);
|
||||
|
||||
boatStatuses.add(boatStatusDecoder.getMessage());
|
||||
}
|
||||
|
||||
|
||||
message = new RaceStatus(
|
||||
versionNum,
|
||||
time,
|
||||
raceID,
|
||||
raceStatus,
|
||||
expectedStart,
|
||||
windDirection,
|
||||
windSpeed,
|
||||
raceType,
|
||||
boatStatuses );
|
||||
}
|
||||
|
||||
public byte getVersionNum() {
|
||||
return versionNum;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public int getRace() {
|
||||
return race;
|
||||
}
|
||||
|
||||
public byte getRaceState() {
|
||||
return raceState;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public int getRaceWindDir() {
|
||||
return raceWindDir;
|
||||
}
|
||||
|
||||
public short getRaceWindSpeed() {
|
||||
return raceWindSpeed;
|
||||
}
|
||||
|
||||
public int getNumberOfBoats() {
|
||||
return numberOfBoats;
|
||||
}
|
||||
|
||||
public int getRaceType() {
|
||||
return raceType;
|
||||
}
|
||||
|
||||
public ArrayList<BoatStatus> getBoats() {
|
||||
return boats;
|
||||
/**
|
||||
* Returns the decoded message.
|
||||
* @return The decoded message.
|
||||
*/
|
||||
public RaceStatus getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user