Projet_JAVA_P2P_STRI2A/src/protocolP2P/HashRequest.java
2020-03-04 17:40:21 +01:00

159 lines
4.6 KiB
Java

package protocolP2P;
import protocolP2P.Payload;
import protocolP2P.HashAlgorithm;
import java.io.UnsupportedEncodingException;
import exception.TransmissionError;
import exception.SizeError;
import exception.ProtocolError;
import exception.InternalError;
import tools.BytesArrayTools;
/** Representation of payload for hash request.
* @author Louis Royer
* @author Flavien Haas
* @author JS Auge
* @version 1.0
*/
public class HashRequest extends Payload {
private String filename;
private HashAlgorithm[] algoList;
private static final int FILENAME_SIZE_POSITION = PAYLOAD_START_POSITION;
private static final int FILENAME_POSITION = FILENAME_SIZE_POSITION + 4;
/** Constructor (typically used by the server) with a filename parameter.
* @param filename name of the file to download. Must not be empty.
* @param algoList List of hash algorithms used
* @throws InternalError
*
*/
public HashRequest(String filename, HashAlgorithm[] algoList) throws InternalError {
super(RequestResponseCode.HASH_REQUEST);
/* assert to help debugging */
assert filename.length() != 0 : "Size of filename in HashRequest must not be empty";
if (filename.length() == 0) {
throw new InternalError();
}
this.filename = filename;
assert algoList.length != 0 : "Hash algorithms list must not be empty";
if (algoList.length == 0) {
throw new InternalError();
}
this.algoList = algoList;
}
/** Constructor (typically used by client) with a byte[] parameter containing the Packet received.
* @param packet the full Packet received
* @throws SizeError
* @throws InternalError
* @throws ProtocolError
* @throws TransmissionError
*/
protected HashRequest(byte[] packet) throws TransmissionError, SizeError, ProtocolError, InternalError {
super(packet);
/* assert to help debugging */
assert requestResponseCode == RequestResponseCode.HASH_REQUEST : "HashRequest subclass is incompatible with this Packet, request/response code must be checked before using this constructor";
/* InternalErrorException */
if (requestResponseCode!= RequestResponseCode.HASH_REQUEST) {
throw new InternalError();
}
/* Read filename */
int filenameSize = BytesArrayTools.readInt(packet, FILENAME_SIZE_POSITION);
try {
filename = new String(packet, FILENAME_POSITION, filenameSize, "UTF-8");
} catch (UnsupportedEncodingException e) {
throw new InternalError();
}
int size = getPayloadSize(packet);
try {
String[] l = (new String(packet, FILENAME_POSITION + filenameSize, size, "UTF-8")).split("\n");
int i = 0;
for(String algo : l) {
algoList[i] = HashAlgorithm.fromName(algo);
i++;
}
} catch (UnsupportedEncodingException e) {
throw new InternalError();
}
}
/** 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 {
// compute size
int filenameSize = filename.length();
int size = FILENAME_POSITION + filenameSize;
for (HashAlgorithm h : algoList) {
size += h.getName().length();
size += 1; // size for '\n'
}
size -=1; // remove trailing '\n'
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 - FILENAME_SIZE_POSITION, packet);
BytesArrayTools.write(packet, FILENAME_SIZE_POSITION, filenameSize);
// Write filename
int bCount = FILENAME_POSITION;
try {
byte[] sb = filename.getBytes("UTF-8");
for(byte b : sb) {
packet[bCount] = b;
bCount += 1;
}
} catch (UnsupportedEncodingException e) {
throw new InternalError();
}
boolean firstIter = true;
for(HashAlgorithm h : algoList) {
String s = h.getName();
if (!firstIter) {
firstIter = false;
try {
packet[bCount] = "\n".getBytes("UTF-8")[0]; // separator
} catch (UnsupportedEncodingException e) {
throw new InternalError();
}
bCount += 1;
}
// Copy algoname
try {
byte[] sb = s.getBytes("UTF-8");
for(byte b : sb) {
packet[bCount] = b;
bCount += 1;
}
} catch (UnsupportedEncodingException e) {
throw new InternalError();
}
}
return packet;
}
/** AlgoList getter.
* @return List of HashAlgorithms
*/
public HashAlgorithm[] getAlgoList() {
return algoList;
}
/** Filename getter.
* @return filename
*/
public String getFilename() {
return filename;
}
}