Added RaceStartStatusEncoder.
Added RaceStartTypeEnum. Refactored RaceStartStatusDecoder to implement the MessageDecoder interface. Documented RaceStartStatus, and it actually exposes its properties now. Updated RaceStartStatusDecoderTest. issue #35 #36 #story[1095]
This commit is contained in:
@@ -164,8 +164,8 @@ public class BinaryMessageDecoder {
|
||||
|
||||
case RACESTARTSTATUS:
|
||||
//System.out.println("Race Start Status Message");
|
||||
RaceStartStatusDecoder rssDecoder = new RaceStartStatusDecoder(messageBody);
|
||||
return new RaceStartStatus(rssDecoder.getTime(), rssDecoder.getAck(), rssDecoder.getStartTime(), rssDecoder.getRaceID(), rssDecoder. getNotification());
|
||||
RaceStartStatusDecoder rssDecoder = new RaceStartStatusDecoder();
|
||||
return rssDecoder.decode(messageBody);
|
||||
|
||||
case YACHTEVENTCODE:
|
||||
//System.out.println("Yacht Action Code!");
|
||||
|
||||
@@ -37,7 +37,7 @@ public class DecoderFactory {
|
||||
|
||||
case XMLMESSAGE: return new XMLMessageDecoder();
|
||||
|
||||
//case RACESTARTSTATUS: return new RaceStartStatusDecoder();//TODO
|
||||
case RACESTARTSTATUS: return new RaceStartStatusDecoder();
|
||||
|
||||
//case YACHTEVENTCODE: return new YachtEventCodeDecoder();//TODO
|
||||
|
||||
|
||||
@@ -1,66 +1,81 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.Enums.RaceStartTypeEnum;
|
||||
import network.Messages.RaceStartStatus;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static network.Utils.ByteConverter.*;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hba56 on 21/04/17.
|
||||
* Decodes {@link RaceStartStatus} messages.
|
||||
*/
|
||||
public class RaceStartStatusDecoder {
|
||||
private byte messageVersion;
|
||||
private byte[] timestamp;
|
||||
private byte[] ackNumber;
|
||||
private byte[] raceStartTime;
|
||||
private byte[] raceIdentifier;
|
||||
private byte notificationType;
|
||||
public class RaceStartStatusDecoder implements MessageDecoder {
|
||||
|
||||
private long time;
|
||||
private short ack;
|
||||
private long startTime;
|
||||
private int raceID;
|
||||
private char notification;
|
||||
/**
|
||||
* The encoded message.
|
||||
*/
|
||||
private byte[] encodedMessage;
|
||||
|
||||
/**
|
||||
* The decoded message.
|
||||
*/
|
||||
private RaceStartStatus message;
|
||||
|
||||
|
||||
public RaceStartStatusDecoder(byte[] encodedRaceStartStatus) {
|
||||
messageVersion = encodedRaceStartStatus[0];
|
||||
timestamp = Arrays.copyOfRange(encodedRaceStartStatus, 1, 7);
|
||||
ackNumber = Arrays.copyOfRange(encodedRaceStartStatus, 7, 9);
|
||||
raceStartTime = Arrays.copyOfRange(encodedRaceStartStatus, 9, 15);
|
||||
raceIdentifier = Arrays.copyOfRange(encodedRaceStartStatus, 15, 19);
|
||||
notificationType = encodedRaceStartStatus[19];
|
||||
|
||||
time = bytesToLong(timestamp);
|
||||
ack = bytesToShort(ackNumber);
|
||||
startTime = bytesToLong(raceStartTime);
|
||||
raceID = bytesToInt(raceIdentifier);
|
||||
notification = bytesToChar(notificationType);
|
||||
/**
|
||||
* Constructs a decoder to decode a given message.
|
||||
*/
|
||||
public RaceStartStatusDecoder() {
|
||||
}
|
||||
|
||||
|
||||
public byte getMessageVersion() {
|
||||
return messageVersion;
|
||||
@Override
|
||||
public AC35Data decode(byte[] encodedMessage) {
|
||||
this.encodedMessage = encodedMessage;
|
||||
|
||||
|
||||
byte messageVersion = encodedMessage[0];
|
||||
|
||||
byte[] timestamp = Arrays.copyOfRange(encodedMessage, 1, 7);
|
||||
long time = bytesToLong(timestamp);
|
||||
|
||||
byte[] ackNumber = Arrays.copyOfRange(encodedMessage, 7, 9);
|
||||
short ack = bytesToShort(ackNumber);
|
||||
|
||||
byte[] raceStartTime = Arrays.copyOfRange(encodedMessage, 9, 15);
|
||||
long startTime = bytesToLong(raceStartTime);
|
||||
|
||||
byte[] raceIdentifier = Arrays.copyOfRange(encodedMessage, 15, 19);
|
||||
int raceID = bytesToInt(raceIdentifier);
|
||||
|
||||
byte notificationType = encodedMessage[19];
|
||||
|
||||
|
||||
|
||||
message = new RaceStartStatus(
|
||||
messageVersion,
|
||||
time,
|
||||
ack,
|
||||
startTime,
|
||||
raceID,
|
||||
RaceStartTypeEnum.fromByte(notificationType)
|
||||
);
|
||||
|
||||
return message;
|
||||
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public short getAck() {
|
||||
return ack;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
public int getRaceID() {
|
||||
return raceID;
|
||||
}
|
||||
|
||||
public char getNotification() {
|
||||
return notification;
|
||||
/**
|
||||
* Returns the decoded message.
|
||||
* @return The decoded message.
|
||||
*/
|
||||
public RaceStartStatus getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public class EncoderFactory {
|
||||
|
||||
case XMLMESSAGE: return new XMLMessageEncoder();
|
||||
|
||||
//case RACESTARTSTATUS: return new RaceStartStatusEncoder();//TODO
|
||||
case RACESTARTSTATUS: return new RaceStartStatusEncoder();
|
||||
|
||||
//case YACHTEVENTCODE: return new YachtEventCodeEncoder();//TODO
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package network.MessageEncoders;
|
||||
|
||||
|
||||
import network.Messages.AC35Data;
|
||||
import network.Messages.RaceStartStatus;
|
||||
import network.Utils.ByteConverter;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static network.Utils.ByteConverter.intToBytes;
|
||||
import static network.Utils.ByteConverter.longToBytes;
|
||||
|
||||
/**
|
||||
* This encoder can encode a {@link RaceStartStatus} message.
|
||||
*/
|
||||
public class RaceStartStatusEncoder implements MessageEncoder {
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public RaceStartStatusEncoder() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public byte[] encode(AC35Data message) {
|
||||
|
||||
//Downcast.
|
||||
RaceStartStatus raceStartStatus = (RaceStartStatus) message;
|
||||
|
||||
|
||||
byte messageVersion = raceStartStatus.getMessageVersionNumber();
|
||||
byte[] timestamp = longToBytes(raceStartStatus.getTimestamp(), 6);
|
||||
byte[] ackNumber = intToBytes(raceStartStatus.getAckNum(), 2);
|
||||
byte[] raceStartTime = longToBytes(raceStartStatus.getRaceStartTime(), 6);
|
||||
byte[] raceIdentifier = intToBytes(raceStartStatus.getRaceID());
|
||||
byte[] notificationType = intToBytes(raceStartStatus.getNotificationType().getValue(), 1);
|
||||
|
||||
ByteBuffer result = ByteBuffer.allocate(20);
|
||||
result.put(messageVersion);
|
||||
result.put(timestamp);
|
||||
result.put(ackNumber);
|
||||
result.put(raceStartTime);
|
||||
result.put(raceIdentifier);
|
||||
result.put(notificationType);
|
||||
|
||||
return result.array();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -63,25 +63,6 @@ public class RaceVisionByteEncoder {
|
||||
return result.array();
|
||||
}
|
||||
|
||||
public static byte[] raceStartStatus(long time, short ack, long startTime, int raceID, char notification){
|
||||
int messageVersion = 0b1;
|
||||
byte[] timestamp = longToBytes(time, 6);
|
||||
byte[] ackNumber = intToBytes(ack, 2);
|
||||
byte[] raceStartTime = longToBytes(startTime, 6);
|
||||
int raceIdentifier = raceID;
|
||||
byte[] notificationType = intToBytes(notification, 1);
|
||||
|
||||
ByteBuffer result = ByteBuffer.allocate(20);
|
||||
result.put(intToBytes(messageVersion, 1));
|
||||
result.put(timestamp);
|
||||
result.put(ackNumber);
|
||||
result.put(raceStartTime);
|
||||
result.put(intToBytes(raceIdentifier));
|
||||
result.put(notificationType);
|
||||
|
||||
return result.array();
|
||||
}
|
||||
|
||||
public static byte[] yachtEventCode(long time, short acknowledgeNumber, int raceID, int destSourceID, int incidentID,
|
||||
int eventID){
|
||||
int messageVersion = 0b10;
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
package network.Messages.Enums;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Enumeration that encapsulates the various types race start status notifications. See AC35 streaming spec, 4.5.
|
||||
*/
|
||||
public enum RaceStartTypeEnum {
|
||||
|
||||
|
||||
/**
|
||||
* The race start time is being set.
|
||||
*/
|
||||
SET_RACE_START(1),
|
||||
|
||||
/**
|
||||
* The race has been postponed.
|
||||
*/
|
||||
RACE_POSTPONED(2),
|
||||
|
||||
/**
|
||||
* The race has been abandoned.
|
||||
*/
|
||||
RACE_ABANDONED(3),
|
||||
|
||||
/**
|
||||
* The race has been terminated.
|
||||
*/
|
||||
RACE_TERMINATED(4),
|
||||
|
||||
/**
|
||||
* Used to indicate that a given byte value is invalid.
|
||||
*/
|
||||
NOT_A_TYPE(-1);
|
||||
|
||||
|
||||
/**
|
||||
* Primitive value of the enum.
|
||||
*/
|
||||
private byte value;
|
||||
|
||||
|
||||
/**
|
||||
* Ctor. Creates a RaceStartTypeEnum from a given primitive integer value, cast to a byte.
|
||||
* @param value Integer, which is cast to byte, to construct from.
|
||||
*/
|
||||
private RaceStartTypeEnum(int value) {
|
||||
this.value = (byte) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the primitive value of the enum.
|
||||
* @return Primitive value of the enum.
|
||||
*/
|
||||
public byte getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stores a mapping between Byte values and RaceStartTypeEnum values.
|
||||
*/
|
||||
private static final Map<Byte, RaceStartTypeEnum> byteToTypeMap = new HashMap<>();
|
||||
|
||||
|
||||
/*
|
||||
Static initialization block. Initializes the byteToTypeMap.
|
||||
*/
|
||||
static {
|
||||
for (RaceStartTypeEnum type : RaceStartTypeEnum.values()) {
|
||||
RaceStartTypeEnum.byteToTypeMap.put(type.value, type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the enumeration value which corresponds to a given byte value.
|
||||
* @param startTypeEnum Byte value to convert to a RaceStartTypeEnum value.
|
||||
* @return The RaceStartTypeEnum value which corresponds to the given byte value.
|
||||
*/
|
||||
public static RaceStartTypeEnum fromByte(byte startTypeEnum) {
|
||||
//Gets the corresponding MessageType from the map.
|
||||
RaceStartTypeEnum type = RaceStartTypeEnum.byteToTypeMap.get(startTypeEnum);
|
||||
|
||||
if (type == null) {
|
||||
//If the byte value wasn't found, return the NOT_A_TYPE RaceStartTypeEnum.
|
||||
return RaceStartTypeEnum.NOT_A_TYPE;
|
||||
} else {
|
||||
//Otherwise, return the RaceStartTypeEnum.
|
||||
return type;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -2,20 +2,63 @@ package network.Messages;
|
||||
|
||||
|
||||
import network.Messages.Enums.MessageType;
|
||||
import network.Messages.Enums.RaceStartTypeEnum;
|
||||
|
||||
|
||||
/**
|
||||
* Created by fwy13 on 25/04/17.
|
||||
* Represents a RaceStartStatus message from the API, section 4.5.
|
||||
*/
|
||||
public class RaceStartStatus extends AC35Data {
|
||||
|
||||
private long timestamp;
|
||||
private int ackNum;
|
||||
private long raceStartTime;
|
||||
private int raceID;
|
||||
private int notificationType;
|
||||
/**
|
||||
* The current version number of this message type.
|
||||
*/
|
||||
public static final byte currentMessageVersionNumber = 1;
|
||||
|
||||
public RaceStartStatus(long timestamp, int ackNum, long raceStartTime, int raceID, int notificationType){
|
||||
|
||||
/**
|
||||
* The version number of this message.
|
||||
*/
|
||||
private byte messageVersionNumber;
|
||||
|
||||
/**
|
||||
* The time at which this message was created. Milliseconds since unix epoch.
|
||||
*/
|
||||
private long timestamp;
|
||||
|
||||
/**
|
||||
* Sequence number of message.
|
||||
*/
|
||||
private int ackNum;
|
||||
|
||||
/**
|
||||
* The time the race is expected to start at. Milliseconds since unix epoch.
|
||||
*/
|
||||
private long raceStartTime;
|
||||
|
||||
/**
|
||||
* The ID of the race this message relates to.
|
||||
*/
|
||||
private int raceID;
|
||||
|
||||
/**
|
||||
* The type of notification this is.
|
||||
*/
|
||||
private RaceStartTypeEnum notificationType;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a RaceStartStatus message with the given parameters.
|
||||
* @param messageVersionNumber Version number of the message.
|
||||
* @param timestamp The timestamp at which this message was generated.
|
||||
* @param ackNum The sequence number of this message.
|
||||
* @param raceStartTime The expected race start time.
|
||||
* @param raceID The ID of the race this message relates to.
|
||||
* @param notificationType The type of notification this is.
|
||||
*/
|
||||
public RaceStartStatus(byte messageVersionNumber, long timestamp, int ackNum, long raceStartTime, int raceID, RaceStartTypeEnum notificationType) {
|
||||
super(MessageType.RACESTARTSTATUS);
|
||||
this.messageVersionNumber = messageVersionNumber;
|
||||
this.timestamp = timestamp;
|
||||
this.ackNum = ackNum;
|
||||
this.raceStartTime = raceStartTime;
|
||||
@@ -23,4 +66,52 @@ public class RaceStartStatus extends AC35Data {
|
||||
this.notificationType = notificationType;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the version number of this message.
|
||||
* @return Version number of this message.
|
||||
*/
|
||||
public byte getMessageVersionNumber() {
|
||||
return messageVersionNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time at which this message was generated. Milliseconds since unix epoch.
|
||||
* @return Time at which this message was generated.
|
||||
*/
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sequence number of this message.
|
||||
* @return Sequence number of this message.
|
||||
*/
|
||||
public int getAckNum() {
|
||||
return ackNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expected race start time. Milliseconds since unix epoch.
|
||||
* @return Expected race start time.
|
||||
*/
|
||||
public long getRaceStartTime() {
|
||||
return raceStartTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the race ID this message relates to.
|
||||
* @return Race ID this message relates to.
|
||||
*/
|
||||
public int getRaceID() {
|
||||
return raceID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of start status notification this message is.
|
||||
* @return The type of notification this is.
|
||||
*/
|
||||
public RaceStartTypeEnum getNotificationType() {
|
||||
return notificationType;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user