Projet_JAVA_P2P_STRI2A/src/protocolP2P/FilePart.java

182 lines
6.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package protocolP2P;
import protocolP2P.Payload;
import protocolP2P.RequestResponseCode;
import localException.ProtocolError;
import localException.InternalError;
import localException.SizeError;
import localException.TransmissionError;
import tools.BytesArrayTools;
/** Representation of payload for load response.
* @author Louis Royer
* @author Flavien Haas
* @author JS Auge
* @version 1.0
*/
public class FilePart extends Payload {
private String filename;
private long totalSize;
private long offset;
private byte[] partialContent;
static final private int OFFSET_POSITION = PAYLOAD_START_POSITION;
static final private int TOTAL_FILESIZE_POSITION = OFFSET_POSITION + 8;
static final private int FILENAME_SIZE_POSITION = TOTAL_FILESIZE_POSITION + 8;
static final private int FILENAME_POSITION = FILENAME_SIZE_POSITION + 4;
/** Constructor (typically used by server) with informations about file part to send as parameters.
* @param filename name of the file to send
* @param totalSize total size of the file to send
* @param offset where in the file begins the part we are sending
* @param partialContent content of the file we send
* @throws InternalError
*/
public FilePart(String filename, long totalSize, long offset, byte[] partialContent) throws InternalError {
super(RequestResponseCode.LOAD_RESPONSE);
/* asserts to help debugging */
assert totalSize >= 0 : "totalSize cannot be negative";
assert partialContent.length != 0 : "partialContent.length cannot be zero, see RRCode.EMPTY_FILE";
assert totalSize >= partialContent.length : "totalSize must be greater than partialContent.length";
assert offset >= 0 : "offset cannot be negative";
assert filename != null : "filename is required";
if (totalSize < 0 || partialContent.length == 0 || totalSize < partialContent.length
|| offset < 0 || filename == null) {
throw new InternalError();
}
this.filename = filename;
this.totalSize = totalSize;
this.offset = offset;
this.partialContent = partialContent;
}
/** Constructor (typically used by client) with Packet received as parameter.
* @param packet the full Packet received
* @throws SizeError
* @throws InternalError
* @throws TransmissionError
*/
protected FilePart(byte[] packet) throws TransmissionError, SizeError, ProtocolError, InternalError {
super(packet);
/* assert to help debugging */
assert requestResponseCode == RequestResponseCode.LOAD_RESPONSE : "FilePart subclass is incompatible with this Packet, request/response code must be checked before using this constructor";
/* InternalErrorException */
if (requestResponseCode != RequestResponseCode.LOAD_RESPONSE) {
throw new InternalError();
}
setOffset(packet); // this can throw SizeError
setTotalSize(packet); // this can throw SizeError
setFilename(packet); // this can throw ProtocolError, SizeError
setPartialContent(packet); // this can throw SizeError
}
/** 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 total size
int size = FILENAME_POSITION + filename.length() + partialContent.length;
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 offset to Packet
BytesArrayTools.write(packet, OFFSET_POSITION, offset);
// write totalSize to Packet
BytesArrayTools.write(packet, TOTAL_FILESIZE_POSITION, totalSize);
// write filenames size to Packet
BytesArrayTools.write(packet, FILENAME_SIZE_POSITION, filename.length());
// write filename to Packet
BytesArrayTools.write(packet, filename, FILENAME_POSITION);
// write partialContent to Packet
BytesArrayTools.write(packet, partialContent, FILENAME_POSITION + filename.length());
return packet;
}
/** Write from Packet into offset.
* @param packet received Packet
* @throws SizeError
*/
private void setOffset(byte[] packet) throws SizeError {
offset = BytesArrayTools.readLong(packet, OFFSET_POSITION);
}
/** Write from Packet into totalSize.
* @param packet received Packet
* @throws SizeError
*/
private void setTotalSize(byte[] packet) throws SizeError {
totalSize = BytesArrayTools.readLong(packet, TOTAL_FILESIZE_POSITION);
}
/** Read filenames size from Packet.
* @param packet received Packet
* @throws ProtocolError
* @throws SizeError
* @return filenames size
*/
private int getFilenameSize(byte[] packet) throws SizeError, ProtocolError {
int size = BytesArrayTools.readInt(packet, FILENAME_SIZE_POSITION); // this can throw SizeError
// filename size cannot be zero
if (size == 0) {
throw new ProtocolError();
}
// cannot excess packet size
if ((FILENAME_POSITION + size) > (getPayloadSize(packet) + OFFSET_POSITION)) {
throw new ProtocolError();
}
return size;
}
/** Write from Packet into filename.
* @param packet received Packet
* @throws ProtocolError
* @throws SizeError
* @throws InternalError
*/
private void setFilename(byte[] packet) throws ProtocolError, SizeError, InternalError {
int filenameSize = getFilenameSize(packet); // this can throw ProtocolError or SizeError
filename = BytesArrayTools.readString(packet, FILENAME_POSITION, filenameSize);
}
/** Write from Packet into partialContent.
* @param packet received Packet
* @throws SizeError
* @throws ProtocolError
*/
private void setPartialContent(byte[] packet) throws ProtocolError, SizeError {
int start = FILENAME_POSITION + getFilenameSize(packet); // this can throw SizeError or ProtocolError
int end = OFFSET_POSITION + getPayloadSize(packet); // this can throw SizeError
partialContent = BytesArrayTools.readByteArray(packet, start, end);
}
/** partialContent getter.
* @return partialcontent
*/
public byte[] getPartialContent() {
return partialContent;
}
/** filename getter.
* @return String
*/
public String getFilename() {
return filename;
}
/** offset getter.
* @return offset
*/
public long getOffset() {
return offset;
}
/** totalSize getter.
* @return totalSize
*/
public long getTotalSize() {
return totalSize;
}
}