package network.MessageEncoders; import network.Exceptions.InvalidMessageException; import network.Exceptions.InvalidMessageTypeException; import network.Messages.*; import static network.Utils.ByteConverter.*; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; /** * Created by fwy13 on 19/04/17. */ public class RaceVisionByteEncoder { public static byte[] displayTextMessage(RaceMessage[] message){ //ByteBuffer result = ByteBuffer.allocate(4 + numLines * 32); int messageVersionNumber = 0b1;//version number short ackNum = 0;//no clue what this does just a placeholder for 2 bytes. byte[] messLines = intToBytes(message.length, 1); // result.putInt(messageVersionNumber); // result.putShort(ackNum); // result.put(messLines); ArrayList messages = new ArrayList(); int size = 4; for (int i = 0; i < message.length; i ++){ int messageLen = message[i].getMessageText().getBytes().length; byte[] messageAsBytes = message[i].getMessageText().getBytes(); if (messageLen < 30){ messageLen = 30; } ByteBuffer mess = ByteBuffer.allocate(2 + messageLen); mess.put(intToBytes(message[i].getLineNumber(), 1)); mess.put(intToBytes(messageLen, 1)); for (int j = 0; j < messageLen; j ++){ mess.put(messageAsBytes[j]); } messages.add(mess.array()); size += 2 + messageLen; } ByteBuffer result = ByteBuffer.allocate(size); result.put(intToBytes(messageVersionNumber, 1)); result.putShort(ackNum); result.put(messLines); for(byte[] mess: messages){ result.put(mess); } 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; byte[] encodeTime = longToBytes(time, 6); short ackNum = acknowledgeNumber; int raceUID = raceID;//TODO chekc if this is an into for a 4 char string. int destSource = destSourceID; int incident = incidentID; byte[] event = intToBytes(eventID, 1); ByteBuffer result = ByteBuffer.allocate(22); result.put(intToBytes(messageVersion, 1)); result.put(encodeTime); result.putShort(ackNum); result.put(intToBytes(raceUID)); result.put(intToBytes(destSource)); result.put(intToBytes(incident)); result.put(event); return result.array(); } public static byte[] chatterText(int messageType, String message){ int messageVersion = 0b1; byte[] type = intToBytes(messageType, 1); byte[] text = message.getBytes(); byte[] length = intToBytes(text.length, 1); ByteBuffer result = ByteBuffer.allocate(3 + text.length); result.put(intToBytes(messageVersion, 1)); result.put(type); result.put(length); result.put(text); return result.array(); } public static byte[] markRounding(int time, int ackNumber, int raceID, int sourceID, int boatStatus, int roundingSide, int markType, int markID){ int messageVersionNumber = 0b1; byte[] byteTime = longToBytes(time, 6); byte[] byteAck = intToBytes(ackNumber, 2); byte[] byteRaceID = intToBytes(raceID, 4); byte[] byteSourceID = intToBytes(sourceID, 4); byte[] byteBoatStatus = intToBytes(boatStatus, 1); byte[] byteRoundingSide = intToBytes(roundingSide, 1); byte[] byteMarkType = intToBytes(markType, 1); byte[] byteMarkID = intToBytes(markID, 1); ByteBuffer result = ByteBuffer.allocate(21); result.put(intToBytes(messageVersionNumber, 1)); result.put(byteTime); result.put(byteAck); result.put(byteRaceID); result.put(byteSourceID); result.put(byteBoatStatus); result.put(byteRoundingSide); result.put(byteMarkType); result.put(byteMarkID); return result.array(); } public static byte[] courseWind(byte windID, ArrayList courseWinds){ int messageVersionNumber = 0b1; byte byteWindID = windID; byte[] loopcount = intToBytes(courseWinds.size(), 1); ByteBuffer result = ByteBuffer.allocate(3 + 20 * courseWinds.size()); result.put(intToBytes(messageVersionNumber, 1)); result.put(byteWindID); result.put(loopcount); for (CourseWind wind: courseWinds){ result.put(intToBytes(wind.getID(), 1)); result.put(longToBytes(wind.getTime(), 6)); result.put(intToBytes(wind.getRaceID(), 4)); result.put(intToBytes(wind.getWindDirection(), 2)); result.put(intToBytes(wind.getWindSpeed(), 2)); result.put(intToBytes(wind.getBestUpwindAngle(), 2)); result.put(intToBytes(wind.getBestDownwindAngle(), 2)); result.put(intToBytes(wind.getFlags(), 1)); } return result.array(); } public static byte[] averageWind(int time, int rawPeriod, int rawSampleSpeed, int period2, int speed2, int period3, int speed3, int period4, int speed4){ int messageVersionNumber = 0b1; byte[] byteTime = longToBytes(time,6); byte[] byteRawPeriod = intToBytes(rawPeriod, 2); byte[] byteRawSpeed = intToBytes(rawSampleSpeed, 2); byte[] bytePeriod2 = intToBytes(period2, 2); byte[] byteSpeed2 = intToBytes(speed2, 2); byte[] bytePeriod3 = intToBytes(period3, 2); byte[] byteSpeed3 = intToBytes(speed3, 2); byte[] bytePeriod4 = intToBytes(period4, 2); byte[] byteSpeed4 = intToBytes(speed4, 2); ByteBuffer result = ByteBuffer.allocate(23); result.put(intToBytes(messageVersionNumber, 1)); result.put(byteTime); result.put(byteRawPeriod); result.put(byteRawSpeed); result.put(bytePeriod2); result.put(byteSpeed2); result.put(bytePeriod3); result.put(byteSpeed3); result.put(bytePeriod4); result.put(byteSpeed4); return result.array(); } /** * Encodes a given message. * @param message Message to encode. * @return Encoded message. * @throws InvalidMessageException If the message cannot be encoded. */ public static byte[] encode(AC35Data message) throws InvalidMessageException { MessageEncoder encoder = null; try { encoder = EncoderFactory.create(message.getType()); } catch (InvalidMessageTypeException e) { throw new InvalidMessageException("Could not create encoder for MessageType: " + message.getType(), e); } byte[] encodedMessage = encoder.encode(message); return encodedMessage; } }