package com.cardshifter.api.serial; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Arrays; import com.cardshifter.api.CardshifterSerializationException; import com.cardshifter.api.LogInterface; import com.cardshifter.api.messages.Message; import com.cardshifter.api.messages.MessageTypeIdResolver; public class ByteTransformer implements CommunicationTransformer { private final LogInterface logger; private final ReflectionInterface refl; public ByteTransformer(LogInterface logger, ReflectionInterface refl) { this.logger = logger; this.refl = refl; } public byte[] transform(Message message) throws CardshifterSerializationException { FieldsCollection<Message> fields = FieldsCollection.gather(message, logger, refl); fields = fields.orderByName().putFirst("command"); return fields.serialize(message); } @Override public void send(Message message, OutputStream out) throws CardshifterSerializationException { // 1. find Fields to serialize // 2. order Fields, pre-process // 3. serialize logger.info("byte send " + message); FieldsCollection<Message> fields = FieldsCollection.gather(message, logger, refl); fields = fields.orderByName().putFirst("command"); byte[] b = fields.serialize(message); logger.info("byte send " + Arrays.toString(b)); try { out.write(b); } catch (IOException e) { throw new CardshifterSerializationException(e); } } @Override public void read(InputStream in, MessageHandler onReceived) throws CardshifterSerializationException { try { logger.info("Started reading " + this); Message message = readOnce(in); logger.info("byte recieve " + message); if (!onReceived.messageReceived(message)) { return; } } catch (Exception e) { throw new CardshifterSerializationException(e); } } public Message readOnce(InputStream in) throws CardshifterSerializationException { try { DataInputStream data = new DataInputStream(in); int numBytes = data.readInt(); logger.info("bytes received " + numBytes); byte[] actualData = new byte[numBytes]; int read = 0; while (read < numBytes) { read += data.read(actualData, read, numBytes - read); } logger.info("bytes data received " + Arrays.toString(actualData)); data = new DataInputStream(new ByteArrayInputStream(actualData)); int typeLength = data.readInt(); String str = readString(data, typeLength); System.out.println(str); Class<?> type = MessageTypeIdResolver.get(str); Message message; try { message = (Message) refl.create(type); } catch (Exception e) { throw new CardshifterSerializationException(e); } FieldsCollection<Message> fields = FieldsCollection.gather(message, logger, refl); fields = fields.orderByName().putFirst("command").skipFirst(); fields.read(message, data); return message; } catch (IOException ex) { throw new CardshifterSerializationException(ex); } } private String readString(DataInputStream data, int numBytes) throws IOException { StringBuilder str = new StringBuilder(numBytes); for (int i = 0; i < numBytes; i++) { str.append(data.readChar()); } return str.toString(); /* byte[] bytes = new byte[numBytes * 2]; data.read(bytes); return new String(bytes, StandardCharsets.UTF_16);*/ } }