Projet_JAVA_P2P_STRI2A/src/protocolP2P/DiscoverResponse.java
2020-03-20 18:23:59 +01:00

118 lines
3.6 KiB
Java

package protocolP2P;
import protocolP2P.Payload;
import tools.HostItem;
import java.util.ArrayList;
import java.util.List;
import localException.InternalError;
import localException.SizeError;
import localException.ProtocolError;
import localException.TransmissionError;
import tools.BytesArrayTools;
/** Representation of payload for discover response.
* @author Louis Royer
* @author Flavien Haas
* @author JS Auge
* @version 1.0
*/
public class DiscoverResponse extends Payload {
private List<HostItem> hostList;
private String filename;
private static final int FILENAME_SIZE_POSITION = PAYLOAD_START_POSITION;
private static final int FILENAME_POSITION = FILENAME_SIZE_POSITION + 4;
/** Constructor with filename (typically used by tracker). If filename is null, it is initialized with "".
* @param filename Name of the file related to the server list.
* @param hostList List of servers
* @throws InternalError
*/
public DiscoverResponse(String filename, List<HostItem> hostList) throws InternalError {
super(RequestResponseCode.DISCOVER_RESPONSE);
this.filename = filename;
this.hostList = hostList;
}
/** Constructor (typically used by server) with a byte[] parameter containing the Packet received.
* @param packet the full Packet received
* @throws SizeError
* @throws InternalError
* @throws ProtocolError
* @throws TransmissionError
*/
protected DiscoverResponse(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError {
super(packet);
int size = getPayloadSize(packet);
/* Read filename size */
int filenameSize = BytesArrayTools.readInt(packet, FILENAME_SIZE_POSITION);
/* Read filename */
filename = BytesArrayTools.readString(packet, FILENAME_POSITION, filenameSize);
// TODO
hostList = new ArrayList<>();
int i = FILENAME_POSITION + filenameSize;
while(i<size) {
int port = BytesArrayTools.readInt16Bits(packet, i);
i += 2;
String hostname = BytesArrayTools.readString(packet, i, "\n");
i += hostname.length();
hostList.add(new HostItem(hostname, port));
}
}
/** Returns a byte[] containing Packet with padding.
* This Packet is still incomplete and should not be send directly.
* ProtocolP2PPacket will use this method to generate the complete Packet.
* @return Packet with padding
* @throws InternalError
*/
protected byte[] toPacket() throws InternalError {
int filenameSize = filename.length();
int hostListSize = 0;
for (HostItem hostItem: hostList) {
hostListSize += (2 + hostItem.getHostname().length() + 1);
}
// compute total size
int size = FILENAME_POSITION + filename.length() + hostListSize;
byte[] packet = new byte[size + 1]; // java initialize all to zero
// set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
// set Payload size
setPayloadSize(size - PAYLOAD_START_POSITION, packet);
// write filename size
BytesArrayTools.write(packet, FILENAME_SIZE_POSITION, filenameSize);
// write filename
BytesArrayTools.write(packet, filename, FILENAME_POSITION);
int i = FILENAME_POSITION + filename.length();
// write hostList
for(HostItem hostItem: hostList) {
try {
BytesArrayTools.write16Bits(packet, i, hostItem.getPort());
i+=2;
String hostname = hostItem.getHostname() + "\n";
BytesArrayTools.write(packet, hostname, i);
i+=hostname.length();
} catch (SizeError e) {
throw new InternalError();
}
}
return packet;
}
/** HostList getter.
* @return hostList
*/
public List<HostItem> getHostList() {
return hostList;
}
/** Filename getter.
* @return filename
*/
public String getFilename() {
return filename;
}
}