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]main
parent
e99ad00294
commit
ce63f58429
@ -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;
|
||||
|
||||
private long time;
|
||||
private short ack;
|
||||
private long startTime;
|
||||
private int raceID;
|
||||
private char notification;
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
public class RaceStartStatusDecoder implements MessageDecoder {
|
||||
|
||||
/**
|
||||
* The encoded message.
|
||||
*/
|
||||
private byte[] encodedMessage;
|
||||
|
||||
public byte getMessageVersion() {
|
||||
return messageVersion;
|
||||
}
|
||||
/**
|
||||
* The decoded message.
|
||||
*/
|
||||
private RaceStartStatus message;
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public short getAck() {
|
||||
return ack;
|
||||
}
|
||||
|
||||
public long getStartTime() {
|
||||
return startTime;
|
||||
/**
|
||||
* Constructs a decoder to decode a given message.
|
||||
*/
|
||||
public RaceStartStatusDecoder() {
|
||||
}
|
||||
|
||||
public int getRaceID() {
|
||||
return raceID;
|
||||
|
||||
@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 char getNotification() {
|
||||
return notification;
|
||||
|
||||
/**
|
||||
* Returns the decoded message.
|
||||
* @return The decoded message.
|
||||
*/
|
||||
public RaceStartStatus getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,29 +1,62 @@
|
||||
package network.MessageDecoders;
|
||||
|
||||
import network.MessageEncoders.RaceVisionByteEncoder;
|
||||
import network.Messages.Enums.RaceStartTypeEnum;
|
||||
import network.Messages.RaceStartStatus;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Created by hba56 on 23/04/17.
|
||||
* Tests for the RaceStartStatus encoder and decoder.
|
||||
*/
|
||||
public class RaceStartStatusDecoderTest {
|
||||
|
||||
|
||||
/**
|
||||
* Tests if a RaceStartStatus message can be encoded and decoded correctly.
|
||||
* @throws Exception Thrown when an error occurs.
|
||||
*/
|
||||
@Test
|
||||
public void getByteArrayTest(){
|
||||
long time = System.currentTimeMillis();
|
||||
public void raceStartStatusEncodeDecodeTest() throws Exception {
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
long time2 = System.currentTimeMillis();
|
||||
byte[] encodedRaceStartStatus = RaceVisionByteEncoder.raceStartStatus(time, (short)1,
|
||||
time2, 2, (char)3);
|
||||
long startTime = System.currentTimeMillis() + 10 * 1000;
|
||||
|
||||
RaceStartStatusDecoder testDecoder = new RaceStartStatusDecoder(encodedRaceStartStatus);
|
||||
RaceStartStatus raceStartStatus = new RaceStartStatus(
|
||||
RaceStartStatus.currentMessageVersionNumber,
|
||||
timestamp,
|
||||
55,
|
||||
startTime,
|
||||
35,
|
||||
RaceStartTypeEnum.SET_RACE_START
|
||||
);
|
||||
|
||||
Assert.assertEquals(0b1, testDecoder.getMessageVersion());
|
||||
Assert.assertEquals(time, testDecoder.getTime());
|
||||
Assert.assertEquals(1, testDecoder.getAck());
|
||||
Assert.assertEquals(time2, testDecoder.getStartTime());
|
||||
Assert.assertEquals(2, testDecoder.getRaceID());
|
||||
Assert.assertEquals((char)3, testDecoder.getNotification());
|
||||
byte[] encodedRaceStartStatus = RaceVisionByteEncoder.encode(raceStartStatus);
|
||||
|
||||
RaceStartStatusDecoder testDecoder = new RaceStartStatusDecoder();
|
||||
testDecoder.decode(encodedRaceStartStatus);
|
||||
RaceStartStatus raceStartStatusDecoded = testDecoder.getMessage();
|
||||
|
||||
compareRaceStartStatusMessages(raceStartStatus, raceStartStatusDecoded);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two RaceStartStatus messages to check that they are the same.
|
||||
* @param original The original message.
|
||||
* @param decoded The decoded message.
|
||||
*/
|
||||
public static void compareRaceStartStatusMessages(RaceStartStatus original, RaceStartStatus decoded) {
|
||||
|
||||
Assert.assertEquals(original.getMessageVersionNumber(), decoded.getMessageVersionNumber());
|
||||
Assert.assertEquals(original.getTimestamp(), decoded.getTimestamp());
|
||||
Assert.assertEquals(original.getAckNum(), decoded.getAckNum());
|
||||
Assert.assertEquals(original.getRaceStartTime(), decoded.getRaceStartTime());
|
||||
Assert.assertEquals(original.getRaceID(), decoded.getRaceID());
|
||||
Assert.assertEquals(original.getNotificationType(), decoded.getNotificationType());
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Loading…
Reference in new issue