package seng302.Networking.MessageDecoders; import seng302.Model.BoatInRace; import seng302.Networking.BoatStatus; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; import java.util.Arrays; /** * Created by hba56 on 21/04/17. */ 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 int raceState; private long startTime; private short raceWindDir; private short raceWindSpeed; private int numberOfBoats; private int raceType; private ArrayList boats = new ArrayList<>(); 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 = byteToInt(raceStatus); startTime = bytesToLong(expectedStart); raceWindDir = bytesToShort(raceWind); raceWindSpeed = bytesToShort(windSpeed); numberOfBoats = byteToInt(numBoats); int boatLoopIndex = 0; for (int i=0; i < numberOfBoats; i++) { byte[] boatBytes = Arrays.copyOfRange(boatsBytes, boatLoopIndex, boatLoopIndex+20); byte[] sourceID = Arrays.copyOfRange(boatBytes, 1, 5); byte boatStatus = boatBytes[5]; byte legNumber = boatBytes[6]; byte numPenaltiesAwarded = boatBytes[7]; byte numPenaltiesServed = boatBytes[8]; byte[] estTimeAtNextMark = Arrays.copyOfRange(boatBytes, 9, 15); byte[] estTimeAtFinish = Arrays.copyOfRange(boatBytes, 15, 20); BoatStatus boat = new BoatStatus(bytesToInt(sourceID),boatStatus, legNumber, numPenaltiesAwarded, numPenaltiesServed, bytesToLong(estTimeAtNextMark), bytesToLong(estTimeAtFinish)); boats.add(boat); boatLoopIndex += 20; } } private int byteToInt(byte bytesInt){ ByteBuffer byteBuffer = ByteBuffer.allocate(4); byteBuffer.order(ByteOrder.BIG_ENDIAN); byteBuffer.put((byte)0); byteBuffer.put((byte)0); byteBuffer.put((byte)0); byteBuffer.put(bytesInt); int intVal = byteBuffer.getInt(0); return intVal; } private short bytesToShort(byte[] bytesShort){ ByteBuffer wrapped = ByteBuffer.wrap(bytesShort); short num = wrapped.getShort(); return num; } private int bytesToInt(byte[] bytesInt){ ByteBuffer wrapped = ByteBuffer.wrap(bytesInt); int num = wrapped.getInt(); return num; } private long bytesToLong(byte[] bytesLong) { ByteBuffer byteBuffer = ByteBuffer.allocate(8); byteBuffer.order(ByteOrder.BIG_ENDIAN); byteBuffer.put((byte) 0); byteBuffer.put((byte) 0); byteBuffer.put(bytesLong); long longVal = byteBuffer.getLong(0); return longVal; } public byte getVersionNum() { return versionNum; } public long getTime() { return time; } public int getRace() { return race; } public int getRaceState() { return raceState; } public long getStartTime() { return startTime; } public short getRaceWindDir() { return raceWindDir; } public short getRaceWindSpeed() { return raceWindSpeed; } public int getNumberOfBoats() { return numberOfBoats; } public int getRaceType() { return raceType; } public ArrayList getBoats() { return boats; } }