package es.um.redes.nanoFiles.tcp.message; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import es.um.redes.nanoFiles.util.FileInfo; public class PeerMessage { public static final byte HASH_LENGTH = 40; private byte opcode; /* * TODO: (Boletín MensajesBinarios) Añadir atributos u otros constructores * específicos para crear mensajes con otros campos, según sea necesario * */ private boolean last; private long fileSize; private String fileHash; private byte filenameLong; private String filenameVal; public PeerMessage() { opcode = PeerMessageOps.OPCODE_INVALID_CODE; } public PeerMessage(byte op) { opcode = op; } /* * TODO: (Boletín MensajesBinarios) Crear métodos getter y setter para obtener * los valores de los atributos de un mensaje. Se aconseja incluir código que * compruebe que no se modifica/obtiene el valor de un campo (atributo) que no * esté definido para el tipo de mensaje dado por "operation". */ public byte getOpcode() { return opcode; } public boolean isLast() { return last; } public void setLast(boolean last) { this.last = last; } public boolean getLast() { return last; } public long getFileSize() { return fileSize; } public void setFileSize(long fileSize) { this.fileSize = fileSize; } public String getFileHash() { return fileHash; } public void setFileHash(String fileHash) { this.fileHash = fileHash; } public byte getFilenameLong() { return filenameLong; } public void setFilenameLong(byte filenameLong) { this.filenameLong = filenameLong; } public String getFilenameVal() { return filenameVal; } public void setFilenameVal(String filenameVal) { this.filenameVal = filenameVal; } /** * Método de clase para parsear los campos de un mensaje y construir el objeto * DirMessage que contiene los datos del mensaje recibido * * @param data El array de bytes recibido * @return Un objeto de esta clase cuyos atributos contienen los datos del * mensaje recibido. * @throws IOException */ public static PeerMessage readMessageFromInputStream(DataInputStream dis) throws IOException { /* * TODO: (Boletín MensajesBinarios) En función del tipo de mensaje, leer del * socket a través del "dis" el resto de campos para ir extrayendo con los * valores y establecer los atributos del un objeto DirMessage que contendrá * toda la información del mensaje, y que será devuelto como resultado. NOTA: * Usar dis.readFully para leer un array de bytes, dis.readInt para leer un * entero, etc. */ byte opcode = dis.readByte(); PeerMessage message = new PeerMessage(opcode); switch (opcode) { case PeerMessageOps.OPCODE_REQUEST_PEER_FILES: case PeerMessageOps.OPCODE_PEER_FILES_ERROR: break; case PeerMessageOps.OPCODE_PEER_FILE: { boolean last = false; byte lastVal = dis.readByte(); if (lastVal == 1) { last = true; } long fileSize = dis.readLong(); byte[] fileHash = new byte[HASH_LENGTH]; dis.readFully(fileHash); byte filenameLong = dis.readByte(); byte[] filenameVal = new byte[filenameLong]; dis.readFully(filenameVal); message.setLast(last); message.setFileSize(fileSize); message.setFileHash(new String(fileHash)); message.setFilenameLong(filenameLong); message.setFilenameVal(new String(filenameVal)); break; } default: System.err.println("PeerMessage.readMessageFromInputStream doesn't know how to parse this message opcode: " + PeerMessageOps.opcodeToOperation(opcode)); System.exit(-1); } return message; } public void writeMessageToOutputStream(DataOutputStream dos) throws IOException { /* * TODO (Boletín MensajesBinarios): Escribir los bytes en los que se codifica el * mensaje en el socket a través del "dos", teniendo en cuenta opcode del * mensaje del que se trata y los campos relevantes en cada caso. NOTA: Usar * dos.write para leer un array de bytes, dos.writeInt para escribir un entero, * etc. */ dos.writeByte(opcode); System.out.println(opcode); switch (opcode) { case PeerMessageOps.OPCODE_REQUEST_PEER_FILES: case PeerMessageOps.OPCODE_PEER_FILES_ERROR: break; case PeerMessageOps.OPCODE_PEER_FILE: { byte lastVal = 0; if (last) { lastVal = 1; } dos.writeByte(lastVal); dos.writeLong(fileSize); dos.write(fileHash.getBytes()); dos.write(filenameLong); dos.write(filenameVal.getBytes()); break; } default: System.err.println("PeerMessage.writeMessageToOutputStream found unexpected message opcode " + opcode + "(" + PeerMessageOps.opcodeToOperation(opcode) + ")"); } } }